Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions src/main/java/com/crowdin/client/branches/BranchesApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
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.DeleteJobStatus;
import com.crowdin.client.core.model.DeleteJobStatusResponseObject;
import com.crowdin.client.core.model.ResponseObject;

import java.util.Collections;

public class BranchesApi extends CrowdinApi {

public BranchesApi(Credentials credentials) {
Expand All @@ -19,6 +23,62 @@ public BranchesApi(Credentials credentials, ClientConfig clientConfig) {
super(credentials, clientConfig);
}

/**
* @param projectId project identifier
* @param branchId branch identifier
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.delete" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/string-based/#operation/api.projects.branches.delete" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public void deleteBranch(Long projectId, Long branchId) throws HttpException, HttpBadRequestException {
this.deleteBranch(projectId, branchId, null);
}

/**
* @param projectId project identifier
* @param branchId branch identifier
* @param isAsync whether to delete the branch asynchronously
* @return delete job status when deleting asynchronously, or {@code null} for a synchronous deletion
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.delete" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/string-based/#operation/api.projects.branches.delete" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseObject<DeleteJobStatus> deleteBranch(Long projectId, Long branchId, Boolean isAsync) throws HttpException, HttpBadRequestException {
String url = this.url + "/projects/" + projectId + "/branches/" + branchId;
if (!Boolean.TRUE.equals(isAsync)) {
this.httpClient.delete(url, new HttpRequestConfig(), Void.class);
return null;
}

DeleteJobStatusResponseObject response = this.httpClient.delete(
url,
new HttpRequestConfig(Collections.emptyMap(), Collections.singletonMap("Prefer", "respond-async")),
DeleteJobStatusResponseObject.class
);
return ResponseObject.of(response.getData());
}

/**
* @param projectId project identifier
* @param branchId branch identifier
* @param jobIdentifier delete job identifier
* @return delete job status
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.jobs.get" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/string-based/#operation/api.projects.branches.jobs.get" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseObject<DeleteJobStatus> checkBranchDeletionStatus(Long projectId, Long branchId, String jobIdentifier) throws HttpException, HttpBadRequestException {
DeleteJobStatusResponseObject response = this.httpClient.get(
this.url + "/projects/" + projectId + "/branches/" + branchId + "/jobs/" + jobIdentifier,
new HttpRequestConfig(),
DeleteJobStatusResponseObject.class
);
return ResponseObject.of(response.getData());
}

/**
* @param projectId project identifier
* @param branchId branch identifier
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/com/crowdin/client/core/model/DeleteJobStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.crowdin.client.core.model;

import lombok.Data;

import java.util.Date;

@Data
public class DeleteJobStatus {

private String identifier;
private String status;
private Integer progress;
private Attributes attributes;
private Date createdAt;
private Date updatedAt;
private Date startedAt;
private Date finishedAt;
private Error error;

@Data
public static class Attributes {

private Long branchId;
private Long directoryId;
private Long fileId;
}

@Data
public static class Error {

private String message;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.crowdin.client.core.model;

import lombok.Data;

@Data
public class DeleteJobStatusResponseObject {

private DeleteJobStatus data;
}
139 changes: 136 additions & 3 deletions src/main/java/com/crowdin/client/sourcefiles/SourceFilesApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.crowdin.client.core.model.*;
import com.crowdin.client.sourcefiles.model.*;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -101,7 +102,51 @@ public ResponseObject<Branch> getBranch(Long projectId, Long branchId) throws Ht
* </ul>
*/
public void deleteBranch(Long projectId, Long branchId) throws HttpException, HttpBadRequestException {
this.httpClient.delete(this.url + "/projects/" + projectId + "/branches/" + branchId, new HttpRequestConfig(), Void.class);
this.deleteBranch(projectId, branchId, null);
}

/**
* @param projectId project identifier
* @param branchId branch identifier
* @param isAsync whether to delete the branch asynchronously
* @return delete job status when deleting asynchronously, or {@code null} for a synchronous deletion
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.projects.branches.delete" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.branches.delete" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseObject<DeleteJobStatus> deleteBranch(Long projectId, Long branchId, Boolean isAsync) throws HttpException, HttpBadRequestException {
String url = this.url + "/projects/" + projectId + "/branches/" + branchId;
if (!Boolean.TRUE.equals(isAsync)) {
this.httpClient.delete(url, new HttpRequestConfig(), Void.class);
return null;
}

DeleteJobStatusResponseObject response = this.httpClient.delete(
url,
new HttpRequestConfig(Collections.emptyMap(), Collections.singletonMap("Prefer", "respond-async")),
DeleteJobStatusResponseObject.class
);
return ResponseObject.of(response.getData());
}

/**
* @param projectId project identifier
* @param branchId branch identifier
* @param jobIdentifier delete job identifier
* @return delete job status
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.projects.branches.jobs.get" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.branches.jobs.get" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseObject<DeleteJobStatus> checkBranchDeletionStatus(Long projectId, Long branchId, String jobIdentifier) throws HttpException, HttpBadRequestException {
DeleteJobStatusResponseObject response = this.httpClient.get(
this.url + "/projects/" + projectId + "/branches/" + branchId + "/jobs/" + jobIdentifier,
new HttpRequestConfig(),
DeleteJobStatusResponseObject.class
);
return ResponseObject.of(response.getData());
}

/**
Expand Down Expand Up @@ -237,7 +282,51 @@ public ResponseObject<Directory> getDirectory(Long projectId, Long directoryId)
* </ul>
*/
public void deleteDirectory(Long projectId, Long directoryId) throws HttpException, HttpBadRequestException {
this.httpClient.delete(this.url + "/projects/" + projectId + "/directories/" + directoryId, new HttpRequestConfig(), Void.class);
this.deleteDirectory(projectId, directoryId, null);
}

/**
* @param projectId project identifier
* @param directoryId directory identifier
* @param isAsync whether to delete the directory asynchronously
* @return delete job status when deleting asynchronously, or {@code null} for a synchronous deletion
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.projects.directories.delete" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.directories.delete" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseObject<DeleteJobStatus> deleteDirectory(Long projectId, Long directoryId, Boolean isAsync) throws HttpException, HttpBadRequestException {
String url = this.url + "/projects/" + projectId + "/directories/" + directoryId;
if (!Boolean.TRUE.equals(isAsync)) {
this.httpClient.delete(url, new HttpRequestConfig(), Void.class);
return null;
}

DeleteJobStatusResponseObject response = this.httpClient.delete(
url,
new HttpRequestConfig(Collections.emptyMap(), Collections.singletonMap("Prefer", "respond-async")),
DeleteJobStatusResponseObject.class
);
return ResponseObject.of(response.getData());
}

/**
* @param projectId project identifier
* @param directoryId directory identifier
* @param jobIdentifier delete job identifier
* @return delete job status
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.projects.directories.jobs.get" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.directories.jobs.get" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseObject<DeleteJobStatus> checkDirectoryDeletionStatus(Long projectId, Long directoryId, String jobIdentifier) throws HttpException, HttpBadRequestException {
DeleteJobStatusResponseObject response = this.httpClient.get(
this.url + "/projects/" + projectId + "/directories/" + directoryId + "/jobs/" + jobIdentifier,
new HttpRequestConfig(),
DeleteJobStatusResponseObject.class
);
return ResponseObject.of(response.getData());
}

/**
Expand Down Expand Up @@ -388,7 +477,51 @@ public ResponseObject<? extends FileInfo> updateOrRestoreFile(Long projectId, Lo
* </ul>
*/
public void deleteFile(Long projectId, Long fileId) throws HttpException, HttpBadRequestException {
this.httpClient.delete(this.url + "/projects/" + projectId + "/files/" + fileId, new HttpRequestConfig(), Void.class);
this.deleteFile(projectId, fileId, null);
}

/**
* @param projectId project identifier
* @param fileId file identifier
* @param isAsync whether to delete the file asynchronously
* @return delete job status when deleting asynchronously, or {@code null} for a synchronous deletion
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.projects.files.delete" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.files.delete" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseObject<DeleteJobStatus> deleteFile(Long projectId, Long fileId, Boolean isAsync) throws HttpException, HttpBadRequestException {
String url = this.url + "/projects/" + projectId + "/files/" + fileId;
if (!Boolean.TRUE.equals(isAsync)) {
this.httpClient.delete(url, new HttpRequestConfig(), Void.class);
return null;
}

DeleteJobStatusResponseObject response = this.httpClient.delete(
url,
new HttpRequestConfig(Collections.emptyMap(), Collections.singletonMap("Prefer", "respond-async")),
DeleteJobStatusResponseObject.class
);
return ResponseObject.of(response.getData());
}

/**
* @param projectId project identifier
* @param fileId file identifier
* @param jobIdentifier delete job identifier
* @return delete job status
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.projects.files.jobs.get" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.files.jobs.get" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseObject<DeleteJobStatus> checkFileDeletionStatus(Long projectId, Long fileId, String jobIdentifier) throws HttpException, HttpBadRequestException {
DeleteJobStatusResponseObject response = this.httpClient.get(
this.url + "/projects/" + projectId + "/files/" + fileId + "/jobs/" + jobIdentifier,
new HttpRequestConfig(),
DeleteJobStatusResponseObject.class
);
return ResponseObject.of(response.getData());
}

/**
Expand Down
27 changes: 27 additions & 0 deletions src/test/java/com/crowdin/client/branches/BranchesApiTest.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package com.crowdin.client.branches;

import com.crowdin.client.branches.model.*;
import com.crowdin.client.core.model.DeleteJobStatus;
import com.crowdin.client.core.model.ResponseObject;
import com.crowdin.client.framework.RequestMock;
import com.crowdin.client.framework.TestClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
Expand All @@ -21,12 +24,16 @@ class BranchesApiTest extends TestClient {
private final Long sourceBranchId = 8L;
private final String cloneId = "aaee1685-c92a-4da6-8a08-c28b4db5cd4a";
private final String mergeId = "50fb3506-4127-4ba8-8296-f97dc7e3e0c3";
private final String deleteJobIdentifier = "50fb3506-4127-4ba8-8296-f97dc7e3e0c3";
private final String name = "cloned";
private final String title = "Cloned Branch";

@Override
public List<RequestMock> getMocks() {
return Arrays.asList(
RequestMock.build(this.url + "/projects/" + projectId + "/branches/" + id, HttpDelete.METHOD_NAME),
RequestMock.build(this.url + "/projects/" + projectId + "/branches/" + id, HttpDelete.METHOD_NAME, "api/branches/deleteJobStatus.json", Collections.emptyMap(), Collections.singletonMap("Prefer", "respond-async")),
RequestMock.build(this.url + "/projects/" + projectId + "/branches/" + id + "/jobs/" + deleteJobIdentifier, HttpGet.METHOD_NAME, "api/branches/deleteJobStatus.json"),
RequestMock.build(this.url + "/projects/" + projectId + "/branches/" + id + "/clones", HttpPost.METHOD_NAME, "api/branches/cloneBranchRequest.json", "api/branches/branchCloneStatus.json"),
RequestMock.build(this.url + "/projects/" + projectId + "/branches/" + id + "/clones/" + cloneId, HttpGet.METHOD_NAME, "api/branches/branchCloneStatus.json"),
RequestMock.build(this.url + "/projects/" + projectId + "/branches/" + id + "/merges", HttpPost.METHOD_NAME, "api/branches/mergeBranchRequest.json", "api/branches/branchMergeStatus.json"),
Expand All @@ -51,6 +58,26 @@ public void checkCloneBranchStatusTest() {
assertEquals(response.getData().getIdentifier(), cloneId);
}

@Test
public void deleteBranchTest() {
this.getBranchesApi().deleteBranch(projectId, id);
}

@Test
public void deleteBranchAsyncTest() {
ResponseObject<DeleteJobStatus> response = this.getBranchesApi().deleteBranch(projectId, id, true);
assertEquals(deleteJobIdentifier, response.getData().getIdentifier());
assertEquals("created", response.getData().getStatus());
assertEquals(id, response.getData().getAttributes().getBranchId());
}

@Test
public void checkBranchDeletionStatusTest() {
ResponseObject<DeleteJobStatus> response = this.getBranchesApi().checkBranchDeletionStatus(projectId, id, deleteJobIdentifier);
assertEquals(deleteJobIdentifier, response.getData().getIdentifier());
assertEquals(id, response.getData().getAttributes().getBranchId());
}

@Test
public void mergeBranchTest() {
MergeBranchRequest request = new MergeBranchRequest();
Expand Down
11 changes: 11 additions & 0 deletions src/test/java/com/crowdin/client/framework/RequestMock.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ public static RequestMock build(String url, String httpMethod, String responseFi
);
}

public static RequestMock build(String url, String httpMethod, String responseFile, Map<String, ?> urlParams, Map<String, ?> headers) {
return new RequestMock(
url,
null,
responseFile,
httpMethod,
urlParams,
headers
);
}

public static RequestMock build(String url, String httpMethod, String responseFile) {
return new RequestMock(
url,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@ private <T, V> T request(String url,
for (int i = 0; i < requestMocks.size(); ++i) {
RequestMock requestMock = requestMocks.get(i);
if (!config.getHeaders().equals(requestMock.getHeaders())) {
throw new AssertionError("No match for request headers : " + requestKey);
continue;
}
Map<String, Object> urlParams = config.getUrlParams().entrySet().stream()
.filter(entry -> entry.getValue().isPresent())
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().get()));
if (!urlParams.equals(requestMock.getUrlParams())) {
throw new AssertionError("No match for url query parameters : " + requestKey);
continue;
}

//request
Expand Down Expand Up @@ -132,10 +132,10 @@ private <T, V> T request(String url,
}
return this.jsonTransformer.parse(responsePayloadMock, clazz);
}
throw new AssertionError("No match for request : " + requestKey);
} catch (Exception e) {
throw new AssertionError("Failed to execute test", e);
}
return null;
}

private String getRequestKey(String url, String httpMethod) {
Expand Down
Loading
Loading