Skip to content

Commit bc53819

Browse files
authored
feat: branch clone and merge api (#240)
1 parent a24d715 commit bc53819

18 files changed

+366
-0
lines changed

src/main/java/com/crowdin/client/Client.java

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.crowdin.client;
22

33
import com.crowdin.client.applications.ApplicationsApi;
4+
import com.crowdin.client.branches.BranchesApi;
45
import com.crowdin.client.bundles.BundlesApi;
56
import com.crowdin.client.clients.ClientsApi;
67
import com.crowdin.client.core.CrowdinApi;
@@ -68,6 +69,7 @@ public class Client extends CrowdinApi {
6869
private final NotificationsApi notificationsApi;
6970
private final ApplicationsApi applicationsApi;
7071
private final ClientsApi clientsApi;
72+
private final BranchesApi branchesApi;
7173

7274
public Client(Credentials credentials) {
7375
super(credentials);
@@ -101,6 +103,7 @@ public Client(Credentials credentials) {
101103
this.notificationsApi = new NotificationsApi(credentials);
102104
this.applicationsApi = new ApplicationsApi(credentials);
103105
this.clientsApi = new ClientsApi(credentials);
106+
this.branchesApi = new BranchesApi(credentials);
104107
}
105108

106109
public Client(Credentials credentials, ClientConfig clientConfig) {
@@ -135,6 +138,7 @@ public Client(Credentials credentials, ClientConfig clientConfig) {
135138
this.notificationsApi = new NotificationsApi(credentials, clientConfig);
136139
this.applicationsApi = new ApplicationsApi(credentials, clientConfig);
137140
this.clientsApi = new ClientsApi(credentials, clientConfig);
141+
this.branchesApi = new BranchesApi(credentials, clientConfig);
138142
}
139143

140144
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package com.crowdin.client.branches;
2+
3+
import com.crowdin.client.branches.model.*;
4+
import com.crowdin.client.core.CrowdinApi;
5+
import com.crowdin.client.core.http.HttpRequestConfig;
6+
import com.crowdin.client.core.http.exceptions.HttpBadRequestException;
7+
import com.crowdin.client.core.http.exceptions.HttpException;
8+
import com.crowdin.client.core.model.ClientConfig;
9+
import com.crowdin.client.core.model.Credentials;
10+
import com.crowdin.client.core.model.ResponseObject;
11+
12+
public class BranchesApi extends CrowdinApi {
13+
14+
public BranchesApi(Credentials credentials) {
15+
super(credentials);
16+
}
17+
18+
public BranchesApi(Credentials credentials, ClientConfig clientConfig) {
19+
super(credentials, clientConfig);
20+
}
21+
22+
/**
23+
* @param projectId project identifier
24+
* @param branchId branch identifier
25+
* @param request request object
26+
* @return clone status
27+
* @see <ul>
28+
* <li><a href="https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.clones.post" target="_blank"><b>API Documentation</b></a></li>
29+
* </ul>
30+
*/
31+
public ResponseObject<BranchCloneStatus> cloneBranch(Long projectId, Long branchId, CloneBranchRequest request) throws HttpException, HttpBadRequestException {
32+
BranchCloneStatusResponseObject branchResponseObject = this.httpClient.post(this.url + "/projects/" + projectId + "/branches/" + branchId + "/clones", request, new HttpRequestConfig(), BranchCloneStatusResponseObject.class);
33+
return ResponseObject.of(branchResponseObject.getData());
34+
}
35+
36+
/**
37+
* @param projectId project identifier
38+
* @param branchId branch identifier
39+
* @param cloneId clone identifier
40+
* @return clone status
41+
* @see <ul>
42+
* <li><a href="https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.clones.get" target="_blank"><b>API Documentation</b></a></li>
43+
* </ul>
44+
*/
45+
public ResponseObject<BranchCloneStatus> checkCloneBranchStatus(Long projectId, Long branchId, String cloneId) throws HttpException, HttpBadRequestException {
46+
BranchCloneStatusResponseObject branchResponseObject = this.httpClient.get(this.url + "/projects/" + projectId + "/branches/" + branchId + "/clones/" + cloneId, new HttpRequestConfig(), BranchCloneStatusResponseObject.class);
47+
return ResponseObject.of(branchResponseObject.getData());
48+
}
49+
50+
/**
51+
* @param projectId project identifier
52+
* @param branchId branch identifier
53+
* @param cloneId clone identifier
54+
* @return cloned branch
55+
* @see <ul>
56+
* <li><a href="https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.clones.branch.get" target="_blank"><b>API Documentation</b></a></li>
57+
* </ul>
58+
*/
59+
public ResponseObject<ClonedBranch> getClonedBranch(Long projectId, Long branchId, String cloneId) throws HttpException, HttpBadRequestException {
60+
ClonedBranchResponseObject branchResponseObject = this.httpClient.get(this.url + "/projects/" + projectId + "/branches/" + branchId + "/clones/" + cloneId + "/branch", new HttpRequestConfig(), ClonedBranchResponseObject.class);
61+
return ResponseObject.of(branchResponseObject.getData());
62+
}
63+
64+
/**
65+
* @param projectId project identifier
66+
* @param branchId branch identifier
67+
* @param request request object
68+
* @return merge status
69+
* @see <ul>
70+
* <li><a href="https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.merges.post" target="_blank"><b>API Documentation</b></a></li>
71+
* </ul>
72+
*/
73+
public ResponseObject<BranchMergeStatus> mergeBranch(Long projectId, Long branchId, MergeBranchRequest request) throws HttpException, HttpBadRequestException {
74+
BranchMergeStatusResponseObject branchResponseObject = this.httpClient.post(this.url + "/projects/" + projectId + "/branches/" + branchId + "/merges", request, new HttpRequestConfig(), BranchMergeStatusResponseObject.class);
75+
return ResponseObject.of(branchResponseObject.getData());
76+
}
77+
78+
/**
79+
* @param projectId project identifier
80+
* @param branchId branch identifier
81+
* @param mergeId merge identifier
82+
* @return merge status
83+
* @see <ul>
84+
* <li><a href="https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.clones.get" target="_blank"><b>API Documentation</b></a></li>
85+
* </ul>
86+
*/
87+
public ResponseObject<BranchMergeStatus> checkMergeBranchStatus(Long projectId, Long branchId, String mergeId) throws HttpException, HttpBadRequestException {
88+
BranchMergeStatusResponseObject branchResponseObject = this.httpClient.get(this.url + "/projects/" + projectId + "/branches/" + branchId + "/merges/" + mergeId, new HttpRequestConfig(), BranchMergeStatusResponseObject.class);
89+
return ResponseObject.of(branchResponseObject.getData());
90+
}
91+
92+
/**
93+
* @param projectId project identifier
94+
* @param branchId branch identifier
95+
* @param mergeId merge identifier
96+
* @return merge summary
97+
* @see <ul>
98+
* <li><a href="https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.merges.summary.get" target="_blank"><b>API Documentation</b></a></li>
99+
* </ul>
100+
*/
101+
public ResponseObject<BranchMergeSummary> getMergeBranchSummary(Long projectId, Long branchId, String mergeId) throws HttpException, HttpBadRequestException {
102+
BranchMergeSummaryResponseObject branchResponseObject = this.httpClient.get(this.url + "/projects/" + projectId + "/branches/" + branchId + "/merges/" + mergeId + "/summary", new HttpRequestConfig(), BranchMergeSummaryResponseObject.class);
103+
return ResponseObject.of(branchResponseObject.getData());
104+
}
105+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.crowdin.client.branches.model;
2+
3+
import lombok.Data;
4+
5+
import java.util.Date;
6+
7+
@Data
8+
public class BranchCloneStatus {
9+
10+
private String identifier;
11+
private String status;
12+
private Integer progress;
13+
private Object attributes;
14+
private Date createdAt;
15+
private Date updatedAt;
16+
private String startedAt;
17+
private String finishedAt;
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.crowdin.client.branches.model;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class BranchCloneStatusResponseObject {
7+
8+
private BranchCloneStatus data;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.crowdin.client.branches.model;
2+
3+
import lombok.Data;
4+
5+
import java.util.Date;
6+
7+
@Data
8+
public class BranchMergeStatus {
9+
10+
private String identifier;
11+
private String status;
12+
private Integer progress;
13+
private BranchMergeStatus.Attributes attributes;
14+
private Date createdAt;
15+
private Date updatedAt;
16+
private String startedAt;
17+
private String finishedAt;
18+
19+
@Data
20+
public static class Attributes {
21+
22+
private Integer sourceBranchId;
23+
private Boolean deleteAfterMerge;
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.crowdin.client.branches.model;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class BranchMergeStatusResponseObject {
7+
8+
private BranchMergeStatus data;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.crowdin.client.branches.model;
2+
3+
import lombok.Data;
4+
5+
import java.util.Map;
6+
7+
@Data
8+
public class BranchMergeSummary {
9+
10+
private String status;
11+
private Long sourceBranchId;
12+
private Long targetBranchId;
13+
private Boolean dryRun;
14+
private Map<String, Long> details;
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.crowdin.client.branches.model;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class BranchMergeSummaryResponseObject {
7+
8+
private BranchMergeSummary data;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.crowdin.client.branches.model;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class CloneBranchRequest {
7+
8+
private String name;
9+
private String title;
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.crowdin.client.branches.model;
2+
3+
import lombok.Data;
4+
5+
import java.util.Date;
6+
7+
@Data
8+
public class ClonedBranch {
9+
10+
private Long id;
11+
private Long projectId;
12+
private String name;
13+
private String title;
14+
private Date createdAt;
15+
private Date updatedAt;
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.crowdin.client.branches.model;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class ClonedBranchResponseObject {
7+
8+
private ClonedBranch data;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.crowdin.client.branches.model;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class MergeBranchRequest {
7+
8+
private Boolean deleteAfterMerge;
9+
private Long sourceBranchId;
10+
private Boolean dryRun;
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.crowdin.client.branches;
2+
3+
import com.crowdin.client.branches.model.*;
4+
import com.crowdin.client.core.model.ResponseObject;
5+
import com.crowdin.client.framework.RequestMock;
6+
import com.crowdin.client.framework.TestClient;
7+
import org.apache.http.client.methods.HttpGet;
8+
import org.apache.http.client.methods.HttpPost;
9+
import org.junit.jupiter.api.Test;
10+
11+
import java.util.Arrays;
12+
import java.util.List;
13+
14+
import static org.junit.jupiter.api.Assertions.assertEquals;
15+
16+
class BranchesApiTest extends TestClient {
17+
18+
private final Long projectId = 1L;
19+
private final Long id = 14L;
20+
private final Long sourceBranchId = 8L;
21+
private final String cloneId = "aaee1685-c92a-4da6-8a08-c28b4db5cd4a";
22+
private final String mergeId = "50fb3506-4127-4ba8-8296-f97dc7e3e0c3";
23+
private final String name = "cloned";
24+
private final String title = "Cloned Branch";
25+
26+
@Override
27+
public List<RequestMock> getMocks() {
28+
return Arrays.asList(
29+
RequestMock.build(this.url + "/projects/" + projectId + "/branches/" + id + "/clones", HttpPost.METHOD_NAME, "api/branches/cloneBranchRequest.json", "api/branches/branchCloneStatus.json"),
30+
RequestMock.build(this.url + "/projects/" + projectId + "/branches/" + id + "/clones/" + cloneId, HttpGet.METHOD_NAME, "api/branches/branchCloneStatus.json"),
31+
RequestMock.build(this.url + "/projects/" + projectId + "/branches/" + id + "/merges", HttpPost.METHOD_NAME, "api/branches/mergeBranchRequest.json", "api/branches/branchMergeStatus.json"),
32+
RequestMock.build(this.url + "/projects/" + projectId + "/branches/" + id + "/merges/" + mergeId, HttpGet.METHOD_NAME, "api/branches/branchMergeStatus.json"),
33+
RequestMock.build(this.url + "/projects/" + projectId + "/branches/" + id + "/merges/" + mergeId + "/summary", HttpGet.METHOD_NAME, "api/branches/branchMergeSummary.json")
34+
);
35+
}
36+
37+
@Test
38+
public void cloneBranchTest() {
39+
CloneBranchRequest request = new CloneBranchRequest();
40+
request.setName(name);
41+
request.setTitle(title);
42+
43+
ResponseObject<BranchCloneStatus> response = this.getBranchesApi().cloneBranch(projectId, id, request);
44+
assertEquals(response.getData().getIdentifier(), cloneId);
45+
}
46+
47+
@Test
48+
public void checkCloneBranchStatusTest() {
49+
ResponseObject<BranchCloneStatus> response = this.getBranchesApi().checkCloneBranchStatus(projectId, id, cloneId);
50+
assertEquals(response.getData().getIdentifier(), cloneId);
51+
}
52+
53+
@Test
54+
public void mergeBranchTest() {
55+
MergeBranchRequest request = new MergeBranchRequest();
56+
request.setDeleteAfterMerge(true);
57+
request.setSourceBranchId(sourceBranchId);
58+
request.setDryRun(false);
59+
60+
ResponseObject<BranchMergeStatus> response = this.getBranchesApi().mergeBranch(projectId, id, request);
61+
assertEquals(response.getData().getIdentifier(), mergeId);
62+
}
63+
64+
@Test
65+
public void checkMergeBranchStatusTest() {
66+
ResponseObject<BranchMergeStatus> response = this.getBranchesApi().checkMergeBranchStatus(projectId, id, mergeId);
67+
assertEquals(response.getData().getIdentifier(), mergeId);
68+
}
69+
70+
@Test
71+
public void getMergeBranchSummaryTest() {
72+
ResponseObject<BranchMergeSummary> response = this.getBranchesApi().getMergeBranchSummary(projectId, id, mergeId);
73+
assertEquals(response.getData().getTargetBranchId(), id);
74+
assertEquals(response.getData().getSourceBranchId(), sourceBranchId);
75+
}
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"data": {
3+
"identifier": "aaee1685-c92a-4da6-8a08-c28b4db5cd4a",
4+
"status": "finished",
5+
"progress": 100,
6+
"attributes": {},
7+
"createdAt": "2024-04-16T16:26:44+00:00",
8+
"updatedAt": "2024-04-16T16:26:44+00:00",
9+
"startedAt": "2024-04-16T16:26:44+00:00",
10+
"finishedAt": "2024-04-16T16:26:44+00:00"
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"data": {
3+
"identifier": "50fb3506-4127-4ba8-8296-f97dc7e3e0c3",
4+
"status": "finished",
5+
"progress": 100,
6+
"attributes": {
7+
"sourceBranchId": 8,
8+
"deleteAfterMerge": false
9+
},
10+
"createdAt": "2019-09-23T11:26:54+00:00",
11+
"updatedAt": "2019-09-23T11:26:54+00:00",
12+
"startedAt": "2019-09-23T11:26:54+00:00",
13+
"finishedAt": "2019-09-23T11:26:54+00:00"
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"data": {
3+
"status": "merged",
4+
"sourceBranchId": 8,
5+
"targetBranchId": 14,
6+
"dryRun": false,
7+
"details": {
8+
"added": 1,
9+
"deleted": 2,
10+
"updated": 3,
11+
"conflicted": 7
12+
}
13+
}
14+
}

0 commit comments

Comments
 (0)