Skip to content

Commit

Permalink
feat: add new Report Archives API endpoints (#242)
Browse files Browse the repository at this point in the history
  • Loading branch information
DecarteAdam authored May 9, 2024
1 parent d7b75c4 commit acb303e
Show file tree
Hide file tree
Showing 9 changed files with 286 additions and 14 deletions.
136 changes: 124 additions & 12 deletions src/main/java/com/crowdin/client/reports/ReportsApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public ResponseObject<GroupReportStatus> generateGroupReport(Long groupId, Gener
}

/**
* @param groupId group identifier
* @param groupId group identifier
* @param reportId report identifier
* @return group report status
* @see <ul>
Expand All @@ -49,7 +49,7 @@ public ResponseObject<GroupReportStatus> checkGroupReportGenerationStatus(Long g
}

/**
* @param groupId group identifier
* @param groupId group identifier
* @param reportId report identifier
* @return report download link
* @see <ul>
Expand Down Expand Up @@ -103,7 +103,7 @@ public ResponseObject<DownloadLink> downloadOrganizationReport(String reportId)

/**
* @param projectId project identifier
* @param request request object
* @param request request object
* @return report status
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.projects.reports.post" target="_blank"><b>API Documentation</b></a></li>
Expand All @@ -117,7 +117,7 @@ public ResponseObject<ReportStatus> generateReport(Long projectId, GenerateRepor

/**
* @param projectId project identifier
* @param reportId report identifier
* @param reportId report identifier
* @return report status
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.projects.reports.get" target="_blank"><b>API Documentation</b></a></li>
Expand All @@ -131,7 +131,7 @@ public ResponseObject<ReportStatus> checkReportGenerationStatus(Long projectId,

/**
* @param projectId project identifier
* @param reportId report identifier
* @param reportId report identifier
* @return download link
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.projects.reports.download.download" target="_blank"><b>API Documentation</b></a></li>
Expand All @@ -145,8 +145,8 @@ public ResponseObject<DownloadLink> downloadReport(Long projectId, String report

/**
* @param projectId project identifier
* @param limit maximum number of items to retrieve (default 25)
* @param offset starting offset in the collection (default 0)
* @param limit maximum number of items to retrieve (default 25)
* @param offset starting offset in the collection (default 0)
* @return list of report settings template
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.projects.reports.settings-templates.getMany" target="_blank"><b>API Documentation</b></a></li>
Expand All @@ -164,7 +164,7 @@ public ResponseList<ReportSettingsTemplate> listReportSettingsTemplate(Long proj

/**
* @param projectId project identifier
* @param request request object
* @param request request object
* @return report settings template
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.projects.reports.settings-templates.post" target="_blank"><b>API Documentation</b></a></li>
Expand All @@ -177,7 +177,7 @@ public ResponseObject<ReportSettingsTemplate> addReportSettingsTemplate(Long pro
}

/**
* @param projectId project identifier
* @param projectId project identifier
* @param reportSettingsTemplateId report settings template identifier
* @return report settings template
* @see <ul>
Expand All @@ -191,9 +191,9 @@ public ResponseObject<ReportSettingsTemplate> getReportSettingsTemplate(Long pro
}

/**
* @param projectId project identifier
* @param projectId project identifier
* @param reportSettingsTemplateId report settings template identifier
* @param request request object
* @param request request object
* @return report settings template
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.projects.reports.settings-templates.patch" target="_blank"><b>API Documentation</b></a></li>
Expand All @@ -206,7 +206,7 @@ public ResponseObject<ReportSettingsTemplate> editReportSettingsTemplate(Long pr
}

/**
* @param projectId project identifier
* @param projectId project identifier
* @param reportSettingsTemplateId report settings template identifier
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.projects.settings-templates.delete" target="_blank"><b>API Documentation</b></a></li>
Expand All @@ -216,4 +216,116 @@ public ResponseObject<ReportSettingsTemplate> editReportSettingsTemplate(Long pr
public void deleteReportSettingsTemplate(Long projectId, Long reportSettingsTemplateId) throws HttpException, HttpBadRequestException {
this.httpClient.delete(this.url + "/projects/" + projectId + "/settings-templates/" + reportSettingsTemplateId, new HttpRequestConfig(), Void.class);
}

// -- REPORT ARCHIVES -- //

/**
* @param userId user identifier
* @param scopeType Filter only project report archives (scopeType=project)
* @param scopeId Filter archives by spicific scope id (default 25)
* @param limit maximum number of items to retrieve (default 25)
* @param offset starting offset in the collection (default 0)
* @return list of report settings template
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.reports.archives.getMany" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.reports.archives.getMany" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseList<ReportArchive> listReportArchives(Long userId, String scopeType, Long scopeId, Integer limit, Integer offset) throws HttpException, HttpBadRequestException {
String url = getReportArchivesPath(userId, "reports/archives/");
Map<String, Optional<Object>> queryParams = HttpRequestConfig.buildUrlParams(
"scopeType", Optional.ofNullable(scopeType),
"scopeId", Optional.ofNullable(scopeId),
"limit", Optional.ofNullable(limit),
"offset", Optional.ofNullable(offset)
);
ReportArchiveList responseObject = this.httpClient.get(url, new HttpRequestConfig(queryParams), ReportArchiveList.class);
return ReportArchiveList.to(responseObject);
}

/**
* @param userId user identifier
* @param archiveId archive identifier
* @return download link
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.users.reports.archives.get" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.reports.archives.get" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseObject<ReportArchive> getReportArchive(Long userId, Long archiveId) throws HttpException, HttpBadRequestException {
String url = getReportArchivesPath(userId, "reports/archives/" + archiveId);
ReportArchiveResponseObject reportArchiveResponseObject = this.httpClient.get(url, new HttpRequestConfig(), ReportArchiveResponseObject.class);
return ResponseObject.of(reportArchiveResponseObject.getData());
}

/**
* @param userId user identifier
* @param archiveId archive identifier
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.users.reports.archives.delete" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.reports.archives.delete" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public void deleteReportArchive(Long userId, Long archiveId) throws HttpException, HttpBadRequestException {
String url = getReportArchivesPath(userId, "reports/archives/" + archiveId);
this.httpClient.delete(url, new HttpRequestConfig(), Void.class);
}

/**
* @param userId user identifier
* @param archiveId archive identifier
* @param request request object
* @return report settings template
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.reports.archives.exports.post" target="_blank"><b>API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.reports.archives.exports.post" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseObject<GroupReportStatus> exportReportArchive(Long userId, Long archiveId, ExportReportRequest request) throws HttpException, HttpBadRequestException {
String url = getReportArchivesPath(userId, "reports/archives/" + archiveId + "/exports");
GroupReportStatusResponseObject responseObject = this.httpClient.post(url, request, new HttpRequestConfig(), GroupReportStatusResponseObject.class);
return ResponseObject.of(responseObject.getData());
}

/**
* @param archiveId archive identifier
* @param exportId export identifier
* @return export report status
* @see <ul>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.reports.archives.exports.get" target="_blank"><b> API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.reports.archives.exports.get" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseObject<GroupReportStatus> checkReportArchiveExportStatus(Long userId, Long archiveId, String exportId) throws HttpException, HttpBadRequestException {
String url = getReportArchivesPath(userId, "reports/archives/" + archiveId + "/exports/" + exportId);
GroupReportStatusResponseObject responseObject = this.httpClient.get(url, new HttpRequestConfig(), GroupReportStatusResponseObject.class);
return ResponseObject.of(responseObject.getData());
}

/**
* @param userId user identifier
* @param archiveId archive identifier
* @param exportId export identifier
* @return report archive download link
* @see <ul>
* <li><a href="https://developer.crowdin.com/api/v2/#operation/api.users.reports.archives.exports.download.get" target="_blank"><b> API Documentation</b></a></li>
* <li><a href="https://developer.crowdin.com/enterprise/api/v2/#operation/api.reports.archives.exports.download.get" target="_blank"><b>Enterprise API Documentation</b></a></li>
* </ul>
*/
public ResponseObject<DownloadLink> downloadReportArchive(Long userId, Long archiveId, String exportId) throws HttpException, HttpBadRequestException {
String url = getReportArchivesPath(userId, "reports/archives" + archiveId + "/exports/" + exportId + "/download");
DownloadLinkResponseObject responseObject = this.httpClient.get(url, new HttpRequestConfig(), DownloadLinkResponseObject.class);
return ResponseObject.of(responseObject.getData());
}

/**
* Build an url with or without userId prefix
*
* @param userId user identifier (for crowdin.com only)
* @param path sub-path of the url
* @return url with userId prefix if exist
*/
private String getReportArchivesPath(Long userId, String path) {
return userId != null ? String.format("%s/users/%d/%s", this.url, userId, path) : String.format("%s/%s", this.url, path);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.crowdin.client.reports.model;

import lombok.Data;

@Data
public class ExportReportRequest {
private ReportsFormat format;
}
17 changes: 17 additions & 0 deletions src/main/java/com/crowdin/client/reports/model/ReportArchive.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.crowdin.client.reports.model;

import lombok.Data;

import java.util.Date;

@Data
public class ReportArchive {
private Long id;
private String scopeType;
private Long scopeId;
private Long userId;
private String name;
private String webUrl;
private Object scheme;
private Date createdAt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.crowdin.client.reports.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 ReportArchiveList {
private List<ReportArchiveResponseObject> data;
private Pagination pagination;

public static ResponseList<ReportArchive> to(ReportArchiveList reportArchiveList) {
return ResponseList.of(
reportArchiveList.getData().stream()
.map(ReportArchiveResponseObject::getData)
.map(ResponseObject::of)
.collect(Collectors.toList()),
reportArchiveList.getPagination()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.crowdin.client.reports.model;

import lombok.Data;

@Data
public class ReportArchiveResponseObject {
private ReportArchive data;
}
71 changes: 69 additions & 2 deletions src/test/java/com/crowdin/client/reports/ReportsApiTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.crowdin.client.reports;

import com.crowdin.client.core.http.exceptions.HttpBadRequestException;
import com.crowdin.client.core.model.*;
import com.crowdin.client.framework.RequestMock;
import com.crowdin.client.framework.TestClient;
Expand All @@ -20,6 +21,7 @@

import static java.util.Collections.singletonList;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;

public class ReportsApiTest extends TestClient {

Expand All @@ -31,6 +33,17 @@ public class ReportsApiTest extends TestClient {
private final String link = "test.com";
private final TimeZone tz = TimeZone.getTimeZone("GMT");

// -- REPORT ARCHIVE --//

private final Long archiveId = 1L;
private final String scopeType = "project";
private final Long scopeId = 1L;
private final Long userId = 1L;
private final String archiveName = "my archive report";
private final String webUrl = "https://crowdin.com/project/project-identifier/reports/archive/1";

private final String exportId = "1";

@Override
public List<RequestMock> getMocks() {
return Arrays.asList(
Expand All @@ -41,7 +54,13 @@ public List<RequestMock> getMocks() {
RequestMock.build(this.url + "/projects/" + projectId + "/reports/settings-templates", HttpPost.METHOD_NAME, "api/reports/addReportSettingsTemplate.json", "api/reports/reportSettingsTemplate.json"),
RequestMock.build(this.url + "/projects/" + projectId + "/reports/settings-templates/" + reportSettingsTemplateId, HttpGet.METHOD_NAME, "api/reports/reportSettingsTemplate.json"),
RequestMock.build(this.url + "/projects/" + projectId + "/reports/settings-templates/" + reportSettingsTemplateId, HttpPatch.METHOD_NAME, "api/reports/editReportSettingsTemplate.json", "api/reports/reportSettingsTemplate.json"),
RequestMock.build(this.url + "/projects/" + projectId + "/settings-templates/" + reportSettingsTemplateId, HttpDelete.METHOD_NAME));
RequestMock.build(this.url + "/projects/" + projectId + "/settings-templates/" + reportSettingsTemplateId, HttpDelete.METHOD_NAME),
RequestMock.build(this.url + "/users/" + userId + "/reports/archives/", HttpGet.METHOD_NAME, "api/reports/listReportArchives.json"),
RequestMock.build(this.url + "/users/" + userId + "/reports/archives/" + archiveId, HttpGet.METHOD_NAME, "api/reports/reportArchive.json"),
RequestMock.build(this.url + "/users/" + userId + "/reports/archives/" + archiveId, HttpDelete.METHOD_NAME),
RequestMock.build(this.url + "/users/" + userId + "/reports/archives/" + archiveId + "/exports", HttpPost.METHOD_NAME, "api/reports/exportReportArchiveReques.json", "api/reports/reportGenerationStatus.json"),
RequestMock.build(this.url + "/users/" + userId + "/reports/archives/" + archiveId + "/exports/" + exportId, HttpGet.METHOD_NAME, "api/reports/reportGenerationStatus.json"),
RequestMock.build(this.url + "/users/" + userId + "/reports/archives" + archiveId + "/exports/" + exportId + "/download", HttpGet.METHOD_NAME, "api/reports/downloadLink.json"));
}

private ReportSettingsTemplate createSettingsTemplate() {
Expand Down Expand Up @@ -100,7 +119,7 @@ public void generateReportTest() {
request.setSchema(schema);
ResponseObject<ReportStatus> reportStatusResponseObject = this.getReportsApi().generateReport(projectId, request);
assertEquals(reportStatusResponseObject.getData().getIdentifier(), id);
assertEquals(new Date(119,Calendar.SEPTEMBER,23,11,26,54), reportStatusResponseObject.getData().getCreatedAt());
assertEquals(new Date(119, Calendar.SEPTEMBER, 23, 11, 26, 54), reportStatusResponseObject.getData().getCreatedAt());
}

@Test
Expand Down Expand Up @@ -157,4 +176,52 @@ public void editReportSettingsTemplateTest() {
public void deleteReportSettingsTemplateTest() {
this.getReportsApi().deleteReportSettingsTemplate(projectId, reportSettingsTemplateId);
}

@Test
public void getListReportArchivesTest() {
ResponseList<ReportArchive> responseObject = this.getReportsApi().listReportArchives(userId, null, null, null, null);
assertEquals(responseObject.getData().size(), 1);
assertEquals(responseObject.getData().get(0).getData().getId(), archiveId);
assertEquals(responseObject.getData().get(0).getData().getScopeType(), scopeType);
assertEquals(responseObject.getData().get(0).getData().getScopeId(), scopeId);
assertEquals(responseObject.getData().get(0).getData().getName(), archiveName);
assertEquals(responseObject.getData().get(0).getData().getWebUrl(), webUrl);
}

@Test
public void getReportArchivesTest() {
ResponseObject<ReportArchive> reportArchive = this.getReportsApi().getReportArchive(userId, archiveId);
assertEquals(reportArchive.getData().getWebUrl(), webUrl);
}

@Test
public void deleteReportArchivesTest() {
try {
this.getReportsApi().deleteReportArchive(userId, archiveId);
// If no exception is thrown, the delete operation is successful
} catch (HttpBadRequestException e) {
fail("Unexpected exception occurred: " + e.getMessage());
}
}

@Test
public void exportReportArchiveTest() {
ExportReportRequest request = new ExportReportRequest();
request.setFormat(ReportsFormat.from("xlsx"));

ResponseObject<GroupReportStatus> exportReportArchive = this.getReportsApi().exportReportArchive(userId, archiveId, request);
assertEquals(exportReportArchive.getData().getAttributes().getFormat(), ReportsFormat.XLSX);
}

@Test
public void checkReportArchiveExportStatusTest() {
ResponseObject<GroupReportStatus> reportStatusResponseObject = this.getReportsApi().checkReportArchiveExportStatus(userId, archiveId, exportId);
assertEquals(reportStatusResponseObject.getData().getIdentifier(), id);
}

@Test
public void downloadReportArchiveTest() {
ResponseObject<DownloadLink> downloadLinkResponseObject = this.getReportsApi().downloadReportArchive(userId, archiveId, exportId);
assertEquals(downloadLinkResponseObject.getData().getUrl(), link);
}
}
3 changes: 3 additions & 0 deletions src/test/resources/api/reports/exportReportArchiveReques.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"format": "xlsx"
}
Loading

0 comments on commit acb303e

Please sign in to comment.