From cf78d76f0f1463e7730b33762472f8a65252fcd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9DAndrei=E2=80=9D?= <”andrei.chirila07121999@gmail.com”> Date: Sat, 6 Dec 2025 23:02:52 +0200 Subject: [PATCH] feat: add support for file references api * Introduced new endpoints to manage the File References API: listing (GET all), GET (for one), POST, and DELETE; * Added new classes to model the asset reference, mainly four classes: the model itself, as ResponseList, as ResponseObject, and one that represents the body request for POST method; * Added unit tests coverage to ensure correct functionality of the methods added. --- .../client/sourcefiles/SourceFilesApi.java | 63 +++++++++++++++++++ .../model/AddAssetReferenceRequest.java | 9 +++ .../sourcefiles/model/AssetReference.java | 23 +++++++ .../model/AssetReferenceResponseList.java | 24 +++++++ .../model/AssetReferenceResponseObject.java | 8 +++ .../sourcefiles/SourceFilesApiTest.java | 40 +++++++++++- .../sourcefiles/addAssetReferenceRequest.json | 4 ++ .../api/sourcefiles/assetReference.json | 15 +++++ .../api/sourcefiles/listAssetReferences.json | 23 +++++++ 9 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/crowdin/client/sourcefiles/model/AddAssetReferenceRequest.java create mode 100644 src/main/java/com/crowdin/client/sourcefiles/model/AssetReference.java create mode 100644 src/main/java/com/crowdin/client/sourcefiles/model/AssetReferenceResponseList.java create mode 100644 src/main/java/com/crowdin/client/sourcefiles/model/AssetReferenceResponseObject.java create mode 100644 src/test/resources/api/sourcefiles/addAssetReferenceRequest.json create mode 100644 src/test/resources/api/sourcefiles/assetReference.json create mode 100644 src/test/resources/api/sourcefiles/listAssetReferences.json diff --git a/src/main/java/com/crowdin/client/sourcefiles/SourceFilesApi.java b/src/main/java/com/crowdin/client/sourcefiles/SourceFilesApi.java index 908570a0c..695246e3c 100644 --- a/src/main/java/com/crowdin/client/sourcefiles/SourceFilesApi.java +++ b/src/main/java/com/crowdin/client/sourcefiles/SourceFilesApi.java @@ -481,4 +481,67 @@ public ResponseObject downloadFilePreview(Long projectId, Long fil DownloadLinkResponseObject downloadLinkResponseObject = this.httpClient.get(this.url + "/projects/" + projectId + "/files/" + fileId + "/preview", new HttpRequestConfig(), DownloadLinkResponseObject.class); return ResponseObject.of(downloadLinkResponseObject.getData()); } + + /** + * @param projectId project identifier + * @param fileId file identifier + * @param limit maximum number of items to retrieve (default 25) + * @param offset starting offset in the collection (default 0) + * @return list of asset references + * @see + */ + public ResponseList listAssetReferences(Long projectId, Long fileId, Integer limit, Integer offset) throws HttpException, HttpBadRequestException { + Map> queryParams = HttpRequestConfig.buildUrlParams( + "limit", Optional.ofNullable(limit), + "offset", Optional.ofNullable(offset) + ); + AssetReferenceResponseList assetReferenceResponseList = this.httpClient.get(this.url + "/projects/" + projectId + "/files/" + fileId + "/references", new HttpRequestConfig(queryParams), AssetReferenceResponseList.class); + return AssetReferenceResponseList.to(assetReferenceResponseList); + } + + /** + * @param projectId project identifier + * @param fileId file identifier + * @param referenceId reference identifier + * @return asset reference + * @see + */ + public ResponseObject getAssetReference(Long projectId, Long fileId, Long referenceId) throws HttpException, HttpBadRequestException { + AssetReferenceResponseObject assetResponseObject = this.httpClient.get(this.url + "/projects/" + projectId + "/files/" + fileId + "/references/" + referenceId, new HttpRequestConfig(), AssetReferenceResponseObject.class); + return ResponseObject.of(assetResponseObject.getData()); + } + + /** + * @param projectId project identifier + * @param fileId file identifier + * @param request request object + * @return newly created asset reference + * @see + */ + public ResponseObject addAssetReference(Long projectId, Long fileId, AddAssetReferenceRequest request) throws HttpException, HttpBadRequestException { + AssetReferenceResponseObject post = this.httpClient.post(this.url + "/projects/" + projectId + "/files/" + fileId + "/references", request, new HttpRequestConfig(), AssetReferenceResponseObject.class); + return ResponseObject.of(post.getData()); + } + + /** + * @param projectId project identifier + * @param fileId file identifier + * @param referenceId reference identifier + * @see + */ + public void deleteAssetReference(Long projectId, Long fileId, Long referenceId) throws HttpException, HttpBadRequestException { + this.httpClient.delete(this.url + "/projects/" + projectId + "/files/" + fileId + "/references/" + referenceId, new HttpRequestConfig(), Void.class); + } } diff --git a/src/main/java/com/crowdin/client/sourcefiles/model/AddAssetReferenceRequest.java b/src/main/java/com/crowdin/client/sourcefiles/model/AddAssetReferenceRequest.java new file mode 100644 index 000000000..672bbb306 --- /dev/null +++ b/src/main/java/com/crowdin/client/sourcefiles/model/AddAssetReferenceRequest.java @@ -0,0 +1,9 @@ +package com.crowdin.client.sourcefiles.model; + +import lombok.Data; + +@Data +public class AddAssetReferenceRequest { + private Long storageId; + private String name; +} diff --git a/src/main/java/com/crowdin/client/sourcefiles/model/AssetReference.java b/src/main/java/com/crowdin/client/sourcefiles/model/AssetReference.java new file mode 100644 index 000000000..8d0276b47 --- /dev/null +++ b/src/main/java/com/crowdin/client/sourcefiles/model/AssetReference.java @@ -0,0 +1,23 @@ +package com.crowdin.client.sourcefiles.model; + +import lombok.Data; + +import java.util.Date; + +@Data +public class AssetReference { + private Long id; + private String name; + private String url; + private User user; + private Date createdAt; + private String mimeType; + + @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/sourcefiles/model/AssetReferenceResponseList.java b/src/main/java/com/crowdin/client/sourcefiles/model/AssetReferenceResponseList.java new file mode 100644 index 000000000..564ec86ca --- /dev/null +++ b/src/main/java/com/crowdin/client/sourcefiles/model/AssetReferenceResponseList.java @@ -0,0 +1,24 @@ +package com.crowdin.client.sourcefiles.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 AssetReferenceResponseList { + private List data; + private Pagination pagination; + + public static ResponseList to(AssetReferenceResponseList assetReferenceList) { + return ResponseList.of(assetReferenceList.getData().stream() + .map(AssetReferenceResponseObject::getData) + .map(ResponseObject::of) + .collect(Collectors.toList()), + assetReferenceList.getPagination() + ); + } +} diff --git a/src/main/java/com/crowdin/client/sourcefiles/model/AssetReferenceResponseObject.java b/src/main/java/com/crowdin/client/sourcefiles/model/AssetReferenceResponseObject.java new file mode 100644 index 000000000..a8020edc1 --- /dev/null +++ b/src/main/java/com/crowdin/client/sourcefiles/model/AssetReferenceResponseObject.java @@ -0,0 +1,8 @@ +package com.crowdin.client.sourcefiles.model; + +import lombok.Data; + +@Data +public class AssetReferenceResponseObject { + private AssetReference data; +} diff --git a/src/test/java/com/crowdin/client/sourcefiles/SourceFilesApiTest.java b/src/test/java/com/crowdin/client/sourcefiles/SourceFilesApiTest.java index b732f394a..88f07adee 100644 --- a/src/test/java/com/crowdin/client/sourcefiles/SourceFilesApiTest.java +++ b/src/test/java/com/crowdin/client/sourcefiles/SourceFilesApiTest.java @@ -35,6 +35,7 @@ public class SourceFilesApiTest extends TestClient { private final Long project4Id = 6L; private final Long fileId = 44L; private final Long storageId = 61L; + private final Long referenceId = 123L; private final Long fileRevisionId = 2L; private final Long buildId = 42L; private final String branchName = "develop-master"; @@ -43,6 +44,7 @@ public class SourceFilesApiTest extends TestClient { private final String directoryName = "main"; private final String directory2Name = "main-#2"; private final String fileName = "umbrella_app.xliff"; + private final String referenceName = "design_reference.png"; private final String context = "Context for translators"; private final String downloadLink = "test.com"; private final String status = "finished"; @@ -95,7 +97,11 @@ public List getMocks() { RequestMock.build(String.format("%s/projects/%d/strings/reviewed-builds", this.url, projectId), HttpGet.METHOD_NAME, "api/sourcefiles/listReviewedSourceFileBuilds.json"), RequestMock.build(String.format("%s/projects/%d/strings/reviewed-builds", url, projectId), HttpPost.METHOD_NAME, "api/sourcefiles/buildReviewedSourceFilesRequest.json", "api/sourcefiles/buildReviewedSourceFiles.json"), RequestMock.build(String.format("%s/projects/%d/strings/reviewed-builds/%d", url, projectId, buildId), HttpGet.METHOD_NAME, "api/sourcefiles/checkReviewedSourceFilesBuildStatus.json"), - RequestMock.build(String.format("%s/projects/%d/strings/reviewed-builds/%d/download", url, projectId, buildId), HttpGet.METHOD_NAME, "api/sourcefiles/downloadReviewedSourceFiles.json") + RequestMock.build(String.format("%s/projects/%d/strings/reviewed-builds/%d/download", url, projectId, buildId), HttpGet.METHOD_NAME, "api/sourcefiles/downloadReviewedSourceFiles.json"), + RequestMock.build(this.url + "/projects/" + projectId + "/files/" + fileId + "/references", HttpGet.METHOD_NAME, "api/sourcefiles/listAssetReferences.json"), + RequestMock.build(this.url + "/projects/" + projectId + "/files/" + fileId + "/references", HttpPost.METHOD_NAME, "api/sourcefiles/addAssetReferenceRequest.json","api/sourcefiles/assetReference.json"), + RequestMock.build(this.url + "/projects/" + projectId + "/files/" + fileId + "/references/" + referenceId, HttpGet.METHOD_NAME, "api/sourcefiles/assetReference.json"), + RequestMock.build(this.url + "/projects/" + projectId + "/files/" + fileId + "/references/" + referenceId, HttpDelete.METHOD_NAME) ); } @@ -640,4 +646,36 @@ private void assertListFilesOrderByIdDesc(ResponseList fileResponseList) { assertNull(((DocxFileImportOptions) importOptions).getSrxStorageId()); } // + + @Test + public void listAssetReferencesTest() { + ResponseList referenceResponseList = this.getSourceFilesApi().listAssetReferences(projectId, fileId, null, null); + assertEquals(1, referenceResponseList.getData().size()); + assertEquals(referenceId, referenceResponseList.getData().get(0).getData().getId()); + assertEquals(referenceName, referenceResponseList.getData().get(0).getData().getName()); + } + + @Test + public void addAssetReferenceTest() { + AddAssetReferenceRequest request = new AddAssetReferenceRequest(); + request.setName(referenceName); + request.setStorageId(67890L); + ResponseObject assetReferenceObject = this.getSourceFilesApi().addAssetReference(projectId, fileId, request); + assertEquals(referenceId, assetReferenceObject.getData().getId()); + assertEquals(referenceName, assetReferenceObject.getData().getName()); + } + + @Test + public void getAssetReferenceTest() { + TimeZone.setDefault(tz); + ResponseObject assetReferenceObject = this.getSourceFilesApi().getAssetReference(projectId, fileId, referenceId); + assertEquals(referenceId, assetReferenceObject.getData().getId()); + assertEquals(referenceName, assetReferenceObject.getData().getName()); + assertEquals(new Date(119,Calendar.SEPTEMBER, 20, 11, 5, 24), assetReferenceObject.getData().getCreatedAt()); + } + + @Test + public void deleteAssetReferenceTest() { + this.getSourceFilesApi().deleteAssetReference(projectId, fileId, referenceId); + } } diff --git a/src/test/resources/api/sourcefiles/addAssetReferenceRequest.json b/src/test/resources/api/sourcefiles/addAssetReferenceRequest.json new file mode 100644 index 000000000..d0dee4098 --- /dev/null +++ b/src/test/resources/api/sourcefiles/addAssetReferenceRequest.json @@ -0,0 +1,4 @@ +{ + "storageId": 67890, + "name": "design_reference.png" +} \ No newline at end of file diff --git a/src/test/resources/api/sourcefiles/assetReference.json b/src/test/resources/api/sourcefiles/assetReference.json new file mode 100644 index 000000000..fe94a73cd --- /dev/null +++ b/src/test/resources/api/sourcefiles/assetReference.json @@ -0,0 +1,15 @@ +{ + "data": { + "id": 123, + "name": "design_reference.png", + "url": "https://example.com/reference/design_reference.png", + "user": { + "id": 1, + "username": "john_doe", + "fullName": "John Smith", + "avatarUrl": "" + }, + "createdAt": "2019-09-20T11:05:24+00:00", + "mimeType": "image/png" + } +} \ No newline at end of file diff --git a/src/test/resources/api/sourcefiles/listAssetReferences.json b/src/test/resources/api/sourcefiles/listAssetReferences.json new file mode 100644 index 000000000..5f4f96eb0 --- /dev/null +++ b/src/test/resources/api/sourcefiles/listAssetReferences.json @@ -0,0 +1,23 @@ +{ + "data": [ + { + "data": { + "id": 123, + "name": "design_reference.png", + "url": "https://example.com/reference/design_reference.png", + "user": { + "id": 1, + "username": "john_doe", + "fullName": "John Smith", + "avatarUrl": "" + }, + "createdAt": "2019-09-20T11:05:24+00:00", + "mimeType": "image/png" + } + } + ], + "pagination": { + "offset": 0, + "limit": 25 + } +} \ No newline at end of file