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
67 changes: 67 additions & 0 deletions src/main/java/com/crowdin/client/applications/ApplicationsApi.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package com.crowdin.client.applications;

import com.crowdin.client.applications.consents.model.AddApplicationConsentRequest;
import com.crowdin.client.applications.consents.model.ApplicationConsent;
import com.crowdin.client.applications.consents.model.ApplicationConsentResponseList;
import com.crowdin.client.applications.consents.model.ApplicationConsentResponseObject;
import com.crowdin.client.applications.consents.model.ListApplicationConsentsParams;
import com.crowdin.client.applications.installations.model.ApplicationInstallation;
import com.crowdin.client.applications.installations.model.ApplicationInstallationResponseList;
import com.crowdin.client.applications.installations.model.ApplicationInstallationResponseObject;
Expand Down Expand Up @@ -180,4 +185,66 @@ public ResponseObject<ApplicationInstallation> editApplicationInstallation(Strin
ApplicationInstallationResponseObject response = this.httpClient.patch(builtUrl, request, new HttpRequestConfig(), ApplicationInstallationResponseObject.class);
return ResponseObject.of(response.getData());
}

/**
* @param params filter, sorting and pagination params
* @return list of application consents
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.applications.consents.getMany" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.applications.consents.getMany" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
Comment thread
andrii-bodnar marked this conversation as resolved.
public ResponseList<ApplicationConsent> listApplicationConsents(ListApplicationConsentsParams params) throws HttpException, HttpBadRequestException {
ListApplicationConsentsParams query = Optional.ofNullable(params).orElse(new ListApplicationConsentsParams());
Map<String, Optional<Object>> queryParams = HttpRequestConfig.buildUrlParams(
"identifier", Optional.ofNullable(query.getIdentifier()),
"orderBy", Optional.ofNullable(OrderByField.generateSortParam(query.getOrderBy())),
"limit", Optional.ofNullable(query.getLimit()),
"offset", Optional.ofNullable(query.getOffset())
);
String builtUrl = String.format("%s/applications/consents", this.url);
ApplicationConsentResponseList response = this.httpClient.get(builtUrl, new HttpRequestConfig(queryParams), ApplicationConsentResponseList.class);
return ApplicationConsentResponseList.to(response);
}

/**
* @param request request object
* @return newly created application consent
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.applications.consents.post" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.applications.consents.post" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseObject<ApplicationConsent> addApplicationConsent(AddApplicationConsentRequest request) throws HttpException, HttpBadRequestException {
String builtUrl = String.format("%s/applications/consents", this.url);
ApplicationConsentResponseObject response = this.httpClient.post(builtUrl, request, new HttpRequestConfig(), ApplicationConsentResponseObject.class);
return ResponseObject.of(response.getData());
}

/**
* @param consentId consent decision identifier
* @param request request object
* @return updated application consent
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.applications.consents.patch" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.applications.consents.patch" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseObject<ApplicationConsent> editApplicationConsent(Long consentId, List<PatchRequest> request) throws HttpException, HttpBadRequestException {
String builtUrl = String.format("%s/applications/consents/%s", this.url, consentId);
ApplicationConsentResponseObject response = this.httpClient.patch(builtUrl, request, new HttpRequestConfig(), ApplicationConsentResponseObject.class);
return ResponseObject.of(response.getData());
}

/**
* @param consentId consent decision identifier
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.applications.consents.delete" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.applications.consents.delete" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public void deleteApplicationConsent(Long consentId) throws HttpException, HttpBadRequestException {
String builtUrl = String.format("%s/applications/consents/%s", this.url, consentId);
this.httpClient.delete(builtUrl, new HttpRequestConfig(), Void.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.crowdin.client.applications.consents.model;

import lombok.Data;

import java.util.List;

@Data
public class AddApplicationConsentRequest {
private String identifier;
private Long installedBy;
private ConsentStatus status;
private List<String> scopes;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.crowdin.client.applications.consents.model;

import lombok.Data;

import java.util.Date;

@Data
public class ApplicationConsent {

private Long id;
private User installedBy;
private String identifier;
private String name;
private ConsentStatus status;
private String[] scopes;
private Date createdAt;
private Date updatedAt;

@Data
public static class User {
private Long id;
private String username;
private String fullName;
private String avatarUrl;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.crowdin.client.applications.consents.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 ApplicationConsentResponseList {

private List<ApplicationConsentResponseObject> data;
private Pagination pagination;

public static ResponseList<ApplicationConsent> to(ApplicationConsentResponseList applicationConsentResponseList) {
return ResponseList.of(
applicationConsentResponseList.getData().stream()
.map(ApplicationConsentResponseObject::getData)
.map(ResponseObject::of)
.collect(Collectors.toList()),
applicationConsentResponseList.getPagination()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.crowdin.client.applications.consents.model;

import lombok.Data;

@Data
public class ApplicationConsentResponseObject {

private ApplicationConsent data;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.crowdin.client.applications.consents.model;

import com.crowdin.client.core.model.EnumConverter;

public enum ConsentStatus implements EnumConverter<ConsentStatus> {
GRANTED, DENIED;

public static ConsentStatus from(String value) {
return ConsentStatus.valueOf(value.toUpperCase());
}

@Override
public String to(ConsentStatus v) {
return v.name().toLowerCase();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.crowdin.client.applications.consents.model;

import com.crowdin.client.core.model.OrderByField;
import com.crowdin.client.core.model.Pagination;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.List;

@Data
@EqualsAndHashCode(callSuper = true)
public class ListApplicationConsentsParams extends Pagination {
private String identifier;
private List<OrderByField> orderBy;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.crowdin.client.applications;

import com.crowdin.client.applications.consents.model.*;
import com.crowdin.client.applications.installations.model.*;
import com.crowdin.client.core.model.PatchOperation;
import com.crowdin.client.core.model.PatchRequest;
Expand All @@ -25,6 +26,8 @@ class ApplicationsApiTest extends TestClient {
private final String path = "path";
private final String builtUrl = this.url + "/applications/" + applicationIdentifier + "/api/" + path;
private final String builtUrlInstallation = this.url + "/applications/installations";
private final String builtUrlConsents = this.url + "/applications/consents";
private final Long consentId = 12L;

@Override
public List<RequestMock> getMocks() {
Expand All @@ -38,7 +41,11 @@ public List<RequestMock> getMocks() {
RequestMock.build(builtUrlInstallation + "/" + applicationIdentifier, HttpDelete.METHOD_NAME),
RequestMock.build(builtUrlInstallation + "/" + applicationIdentifier, HttpPatch.METHOD_NAME, "api/applications/editApplicationInstallation.json", "api/applications/applicationInstallation.json"),
RequestMock.build(builtUrlInstallation, HttpGet.METHOD_NAME, "api/applications/installApplicationList.json"),
RequestMock.build(builtUrlInstallation, HttpPost.METHOD_NAME, "api/applications/installApplication.json", "api/applications/applicationInstallation.json")
RequestMock.build(builtUrlInstallation, HttpPost.METHOD_NAME, "api/applications/installApplication.json", "api/applications/applicationInstallation.json"),
RequestMock.build(builtUrlConsents, HttpGet.METHOD_NAME, "api/applications/listApplicationConsentsResponse.json"),
RequestMock.build(builtUrlConsents, HttpPost.METHOD_NAME, "api/applications/addApplicationConsentRequest.json", "api/applications/applicationConsent.json"),
RequestMock.build(builtUrlConsents + "/" + consentId, HttpPatch.METHOD_NAME, "api/applications/editApplicationConsentRequest.json", "api/applications/applicationConsent.json"),
RequestMock.build(builtUrlConsents + "/" + consentId, HttpDelete.METHOD_NAME)
);
}

Expand Down Expand Up @@ -137,4 +144,42 @@ void editApplicationInstallation() {
assertEquals(response.getData().getIdentifier(), "example-application");
assertEquals(response.getData().getName(), "Application name");
}

@Test
void listApplicationConsents() {
ResponseList<ApplicationConsent> responseList = this.getApplicationsApi().listApplicationConsents(null);
assertNotNull(responseList);
assertEquals(1, responseList.getData().size());
assertEquals(responseList.getData().get(0).getData().getIdentifier(), "example-application");
assertEquals(responseList.getData().get(0).getData().getStatus(), ConsentStatus.GRANTED);
}

@Test
void addApplicationConsent() {
AddApplicationConsentRequest request = new AddApplicationConsentRequest();
request.setIdentifier("example-application");
request.setInstalledBy(consentId);
request.setStatus(ConsentStatus.GRANTED);
request.setScopes(Arrays.asList("project", "tm"));
ResponseObject<ApplicationConsent> response = this.getApplicationsApi().addApplicationConsent(request);
assertNotNull(response);
assertEquals(response.getData().getId(), consentId);
assertEquals(response.getData().getStatus(), ConsentStatus.GRANTED);
}

@Test
void editApplicationConsent() {
PatchRequest request = new PatchRequest();
request.setOp(PatchOperation.REPLACE);
request.setPath("/status");
request.setValue("denied");
ResponseObject<ApplicationConsent> response = this.getApplicationsApi().editApplicationConsent(consentId, singletonList(request));
assertNotNull(response);
assertEquals(response.getData().getId(), consentId);
}

@Test
void deleteApplicationConsent() {
this.getApplicationsApi().deleteApplicationConsent(consentId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"identifier": "example-application",
"installedBy": 12,
"status": "granted",
"scopes": [
"project",
"tm"
]
}
20 changes: 20 additions & 0 deletions src/test/resources/api/applications/applicationConsent.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"data": {
"id": 12,
"installedBy": {
"id": 12,
"username": "john_smith",
"fullName": "John Smith",
"avatarUrl": ""
},
"identifier": "example-application",
"name": "My App",
"status": "granted",
"scopes": [
"project",
"tm"
],
"createdAt": "2026-07-24T10:00:00+00:00",
"updatedAt": "2026-07-24T10:00:00+00:00"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[
{
"op": "replace",
"path": "/status",
"value": "denied"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"data": [
{
"data": {
"id": 12,
"installedBy": {
"id": 12,
"username": "john_smith",
"fullName": "John Smith",
"avatarUrl": ""
},
"identifier": "example-application",
"name": "My App",
"status": "granted",
"scopes": [
"project",
"tm"
],
"createdAt": "2026-07-24T10:00:00+00:00",
"updatedAt": "2026-07-24T10:00:00+00:00"
}
}
],
"pagination": {
"offset": 0,
"limit": 25
}
}
Loading