From bb57d1164f7bf7d72848d27065dfea286ac6bee5 Mon Sep 17 00:00:00 2001 From: Kateryna Oblakevych Date: Wed, 7 Feb 2024 16:31:08 +0200 Subject: [PATCH] feat: label option for screenshot upload command (#721) --- .../com/crowdin/cli/commands/Actions.java | 2 +- .../cli/commands/actions/CliActions.java | 4 +- .../actions/ScreenshotUploadAction.java | 19 +++ .../picocli/ScreenshotUploadSubcommand.java | 5 +- .../cli/commands/actions/CliActionsTest.java | 2 +- .../actions/ScreenshotUploadActionTest.java | 130 ++++++++++++++++-- .../commands/picocli/PicocliTestUtils.java | 2 +- 7 files changed, 147 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/crowdin/cli/commands/Actions.java b/src/main/java/com/crowdin/cli/commands/Actions.java index 997c17d40..7c6eb2047 100644 --- a/src/main/java/com/crowdin/cli/commands/Actions.java +++ b/src/main/java/com/crowdin/cli/commands/Actions.java @@ -123,7 +123,7 @@ NewAction preTranslate( NewAction screenshotList(Long stringId, boolean plainView); - NewAction screenshotUpload(File file, String branchName, String directoryPath, String filePath, boolean autoTag, boolean plainView, boolean noProgress, ProjectClient projectClient); + NewAction screenshotUpload(File file, String branchName, List labelNames, String directoryPath, String filePath, boolean autoTag, boolean plainView, boolean noProgress, ProjectClient projectClient); NewAction screenshotDelete(String name); diff --git a/src/main/java/com/crowdin/cli/commands/actions/CliActions.java b/src/main/java/com/crowdin/cli/commands/actions/CliActions.java index 98518ffd3..6d1daa61f 100644 --- a/src/main/java/com/crowdin/cli/commands/actions/CliActions.java +++ b/src/main/java/com/crowdin/cli/commands/actions/CliActions.java @@ -253,8 +253,8 @@ public NewAction screenshotList(Long string } @Override - public NewAction screenshotUpload(File file, String branchName, String directoryPath, String filePath, boolean autoTag, boolean plainView, boolean noProgress, ProjectClient projectClient) { - return new ScreenshotUploadAction(file, branchName, filePath, directoryPath, autoTag, plainView, noProgress, projectClient); + public NewAction screenshotUpload(File file, String branchName, List labelNames, String directoryPath, String filePath, boolean autoTag, boolean plainView, boolean noProgress, ProjectClient projectClient) { + return new ScreenshotUploadAction(file, branchName, labelNames, filePath, directoryPath, autoTag, plainView, noProgress, projectClient); } @Override diff --git a/src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java b/src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java index d99bd28d6..bbb96faf8 100644 --- a/src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java +++ b/src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java @@ -6,9 +6,11 @@ import com.crowdin.cli.client.ProjectClient; import com.crowdin.cli.commands.NewAction; import com.crowdin.cli.commands.Outputter; +import com.crowdin.cli.commands.functionality.RequestBuilder; import com.crowdin.cli.properties.ProjectProperties; import com.crowdin.cli.utils.Utils; import com.crowdin.cli.utils.console.ConsoleSpinner; +import com.crowdin.client.labels.model.Label; import com.crowdin.client.screenshots.model.AddScreenshotRequest; import com.crowdin.client.screenshots.model.Screenshot; import com.crowdin.client.screenshots.model.UpdateScreenshotRequest; @@ -21,7 +23,9 @@ import java.io.InputStream; import java.nio.file.Files; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; import static com.crowdin.cli.BaseCli.RESOURCE_BUNDLE; import static com.crowdin.cli.utils.console.ExecutionStatus.OK; @@ -33,6 +37,7 @@ class ScreenshotUploadAction implements NewAction labelNames; private final String pathToSourceFile; private final String directoryPath; private final boolean autoTag; @@ -89,6 +94,9 @@ public void act(Outputter out, ProjectProperties properties, ClientScreenshot cl .orElseThrow(() -> new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.dir_not_exists"), directoryPath))); request.setDirectoryId(directory.getId()); } + if (nonNull(labelNames) && !labelNames.isEmpty()) { + request.setLabelIds(prepareLabelIds()); + } request.setStorageId(uploadToStorage(file)); request.setName(file.getName()); request.setAutoTag(autoTag); @@ -120,4 +128,15 @@ private Long uploadToStorage(File fileToUpload) { } return storageId; } + + private Long[] prepareLabelIds() { + Map labels = projectClient.listLabels().stream() + .collect(Collectors.toMap(Label::getTitle, Label::getId)); + labelNames.stream() + .distinct() + .forEach(labelName -> labels.computeIfAbsent(labelName, (title) -> projectClient.addLabel(RequestBuilder.addLabel(title)).getId())); + return labelNames.stream() + .map(labels::get) + .toArray(Long[]::new); + } } diff --git a/src/main/java/com/crowdin/cli/commands/picocli/ScreenshotUploadSubcommand.java b/src/main/java/com/crowdin/cli/commands/picocli/ScreenshotUploadSubcommand.java index a9035ac49..bacfd9998 100644 --- a/src/main/java/com/crowdin/cli/commands/picocli/ScreenshotUploadSubcommand.java +++ b/src/main/java/com/crowdin/cli/commands/picocli/ScreenshotUploadSubcommand.java @@ -34,6 +34,9 @@ class ScreenshotUploadSubcommand extends ActCommandScreenshot{ @CommandLine.Option(names = {"-b", "--branch"}, paramLabel = "...", descriptionKey = "crowdin.screenshot.upload.branch-name", order = -2) protected String branchName; + @CommandLine.Option(names = {"--label"}, paramLabel = "...", descriptionKey = "params.label", order = -2) + protected List labelNames; + @CommandLine.Option(names = {"-d", "--directory"}, paramLabel = "...", descriptionKey = "crowdin.screenshot.upload.directory-path", order = -2) protected String directoryPath; @@ -44,7 +47,7 @@ class ScreenshotUploadSubcommand extends ActCommandScreenshot{ protected NewAction getAction(Actions actions) { Outputter out = new PicocliOutputter(System.out, isAnsi()); ProjectClient projectClient = this.getProjectClient(this.getProperties(propertiesBuilders, out)); - return actions.screenshotUpload(file, branchName, directoryPath, filePath, autoTag, plainView, this.noProgress, projectClient); + return actions.screenshotUpload(file, branchName, labelNames, directoryPath, filePath, autoTag, plainView, this.noProgress, projectClient); } @Override diff --git a/src/test/java/com/crowdin/cli/commands/actions/CliActionsTest.java b/src/test/java/com/crowdin/cli/commands/actions/CliActionsTest.java index fa8800d13..205bd0d5a 100644 --- a/src/test/java/com/crowdin/cli/commands/actions/CliActionsTest.java +++ b/src/test/java/com/crowdin/cli/commands/actions/CliActionsTest.java @@ -134,7 +134,7 @@ void testScreenshotList() { @Test void testScreenshotUpload() { - assertNotNull(actions.screenshotUpload(null, null, null, null, false, false, false, null)); + assertNotNull(actions.screenshotUpload(null, null, null, null, null, false, false, false, null)); } @Test diff --git a/src/test/java/com/crowdin/cli/commands/actions/ScreenshotUploadActionTest.java b/src/test/java/com/crowdin/cli/commands/actions/ScreenshotUploadActionTest.java index 36f2c63a0..492fbde2c 100644 --- a/src/test/java/com/crowdin/cli/commands/actions/ScreenshotUploadActionTest.java +++ b/src/test/java/com/crowdin/cli/commands/actions/ScreenshotUploadActionTest.java @@ -12,6 +12,7 @@ import com.crowdin.cli.properties.helper.FileHelperTest; import com.crowdin.cli.properties.helper.TempProject; import com.crowdin.cli.utils.Utils; +import com.crowdin.client.labels.model.Label; import com.crowdin.client.screenshots.model.AddScreenshotRequest; import com.crowdin.client.screenshots.model.Screenshot; import com.crowdin.client.screenshots.model.UpdateScreenshotRequest; @@ -53,7 +54,7 @@ public void deleteProj() { @ParameterizedTest @MethodSource public void testUploadScreenshot(String fileName, String sourceFilePath, Long sourceFileId, String branchName, - Long branchId, String directoryPath, Long directoryId, boolean autoTag) throws ResponseException { + Long branchId, List labelNames, String directoryPath, Long directoryId, boolean autoTag) throws ResponseException { File fileToUpload = new File(project.getBasePath() + fileName); project.addFile(Utils.normalizePath(fileName)); NewPropertiesWithFilesUtilBuilder pbBuilder = NewPropertiesWithFilesUtilBuilder @@ -102,7 +103,7 @@ public void testUploadScreenshot(String fileName, String sourceFilePath, Long so setId(1L); }}); - action = new ScreenshotUploadAction(fileToUpload, branchName, sourceFilePath, directoryPath, autoTag, false, false, projectClient); + action = new ScreenshotUploadAction(fileToUpload, branchName, labelNames, sourceFilePath, directoryPath, autoTag, false, false, projectClient); action.act(Outputter.getDefault(), pb, client); verify(client).listScreenshots(null); @@ -112,10 +113,10 @@ public void testUploadScreenshot(String fileName, String sourceFilePath, Long so public static Stream testUploadScreenshot() { return Stream.of( - arguments("screenshot.png", null, null, null, null, null, null, false), - arguments("screenshot.png", "/path/to/source/file", 10L, null, null, null, null, true), - arguments("screenshot.png", null, null, "main", 11L, null, null, true), - arguments("screenshot.png", null, null, null, null, "/path/to/directory", 12L, true)); + arguments("screenshot.png", null, null, null, null, null, null, null, false), + arguments("screenshot.png", "/path/to/source/file", 10L, null, null, null, null, null, true), + arguments("screenshot.png", null, null, "main", 11L, null, null, null, true), + arguments("screenshot.png", null, null, null, null, null, "/path/to/directory", 12L, true)); } @Test @@ -148,7 +149,7 @@ public void testUploadScreenshotToUpdate() throws ResponseException { setId(123L); }}); - action = new ScreenshotUploadAction(fileToUpload, null, null, null, false, false, false, projectClient); + action = new ScreenshotUploadAction(fileToUpload, null, null, null, null, false, false, false, projectClient); action.act(Outputter.getDefault(), pb, client); verify(client).listScreenshots(null); @@ -172,7 +173,7 @@ public void testUploadScreenshotNotExistingBranch() { when(projectFull.findBranchByName("main")).thenReturn(Optional.empty()); - action = new ScreenshotUploadAction(new File("screenshot.png"), "main", null, null, true, false, false, projectClient); + action = new ScreenshotUploadAction(new File("screenshot.png"), "main", null, null, null, true, false, false, projectClient); assertThrows(RuntimeException.class, () -> action.act(Outputter.getDefault(), pb, client)); } @@ -192,7 +193,7 @@ public void testUploadScreenshotNotExistingSourceFile() { when(projectFull.getFileInfos()).thenReturn(new ArrayList<>()); - action = new ScreenshotUploadAction(new File("screenshot.png"), null, "/path/to/file", null, true, false, false, projectClient); + action = new ScreenshotUploadAction(new File("screenshot.png"), null, null, "/path/to/file", null, true, false, false, projectClient); assertThrows(RuntimeException.class, () -> action.act(Outputter.getDefault(), pb, client)); } @@ -212,7 +213,114 @@ public void testUploadScreenshotNotExistingDirectory() { when(projectFull.getDirectories()).thenReturn(new HashMap<>()); - action = new ScreenshotUploadAction(new File("screenshot.png"), null, null, "/path/to/directory", true, false, false, projectClient); + action = new ScreenshotUploadAction(new File("screenshot.png"), null, null, null, "/path/to/directory", true, false, false, projectClient); assertThrows(RuntimeException.class, () -> action.act(Outputter.getDefault(), pb, client)); } -} \ No newline at end of file + + @Test + public void testUploadScreenshotWithLabels() throws ResponseException { + File fileToUpload = new File(project.getBasePath() + "screenshot.png"); + project.addFile(Utils.normalizePath("screenshot.png")); + NewPropertiesWithFilesUtilBuilder pbBuilder = NewPropertiesWithFilesUtilBuilder + .minimalBuiltPropertiesBean("*", Utils.PATH_SEPARATOR + "%original_file_name%-CR-%locale%") + .setBasePath(project.getBasePath()); + PropertiesWithFiles pb = pbBuilder.build(); + + AddScreenshotRequest request = new AddScreenshotRequest(); + request.setStorageId(1L); + request.setName("screenshot.png"); + request.setAutoTag(false); + request.setLabelIds(new Long[] {3L, 4L}); + ClientScreenshot client = mock(ClientScreenshot.class); + Label label1 = new Label() {{ + setId(3L); + setTitle("label1"); + }}; + Label label2 = new Label() {{ + setId(4L); + setTitle("label2"); + }}; + + ProjectClient projectClient = mock(ProjectClient.class); + CrowdinProjectFull projectFull = mock(CrowdinProjectFull.class); + + FileInfo fileInfo = mock(FileInfo.class); + + when(projectClient.downloadFullProject()).thenReturn(projectFull); + when(projectFull.getFileInfos()).thenReturn(Arrays.asList(fileInfo)); + + when(projectClient.uploadStorage(eq("screenshot.png"), any())).thenReturn(1L); + when(projectClient.listLabels()).thenReturn(Arrays.asList(label1, label2)); + when(client.listScreenshots(null)).thenReturn(new ArrayList<>()); + + when(client.uploadScreenshot(request)) + .thenReturn(new Screenshot() {{ + setName(request.getName()); + setId(1L); + }}); + + action = new ScreenshotUploadAction(fileToUpload, null, Arrays.asList("label1", "label2"), null, null, false, false, false, projectClient); + action.act(Outputter.getDefault(), pb, client); + + verify(client).listScreenshots(null); + verify(client).uploadScreenshot(request); + verify(projectClient).downloadFullProject(); + verify(projectClient).listLabels(); + verify(projectClient).uploadStorage(any(), any()); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(projectClient); + } + + @Test + public void testUploadScreenshotNotExistingLabel() throws ResponseException { + File fileToUpload = new File(project.getBasePath() + "screenshot.png"); + project.addFile(Utils.normalizePath("screenshot.png")); + NewPropertiesWithFilesUtilBuilder pbBuilder = NewPropertiesWithFilesUtilBuilder + .minimalBuiltPropertiesBean("*", Utils.PATH_SEPARATOR + "%original_file_name%-CR-%locale%") + .setBasePath(project.getBasePath()); + PropertiesWithFiles pb = pbBuilder.build(); + + AddScreenshotRequest request = new AddScreenshotRequest(); + request.setStorageId(1L); + request.setName("screenshot.png"); + request.setAutoTag(false); + request.setLabelIds(new Long[] {3L}); + ClientScreenshot client = mock(ClientScreenshot.class); + + Label label1 = new Label() {{ + setId(3L); + setTitle("label1"); + }}; + + ProjectClient projectClient = mock(ProjectClient.class); + CrowdinProjectFull projectFull = mock(CrowdinProjectFull.class); + + FileInfo fileInfo = mock(FileInfo.class); + + when(projectClient.downloadFullProject()).thenReturn(projectFull); + when(projectFull.getFileInfos()).thenReturn(Arrays.asList(fileInfo)); + + when(projectClient.uploadStorage(eq("screenshot.png"), any())).thenReturn(1L); + when(projectClient.listLabels()).thenReturn(new ArrayList<>()); + when(projectClient.addLabel(any())).thenReturn(label1); + when(client.listScreenshots(null)).thenReturn(new ArrayList<>()); + + when(client.uploadScreenshot(request)) + .thenReturn(new Screenshot() {{ + setName(request.getName()); + setId(1L); + }}); + + action = new ScreenshotUploadAction(fileToUpload, null, Arrays.asList("label1"), null, null, false, false, false, projectClient); + action.act(Outputter.getDefault(), pb, client); + + verify(client).listScreenshots(null); + verify(client).uploadScreenshot(request); + verify(projectClient).downloadFullProject(); + verify(projectClient).listLabels(); + verify(projectClient).addLabel(any()); + verify(projectClient).uploadStorage(any(), any()); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(projectClient); + } +} diff --git a/src/test/java/com/crowdin/cli/commands/picocli/PicocliTestUtils.java b/src/test/java/com/crowdin/cli/commands/picocli/PicocliTestUtils.java index b9f4b566f..607a48ffa 100644 --- a/src/test/java/com/crowdin/cli/commands/picocli/PicocliTestUtils.java +++ b/src/test/java/com/crowdin/cli/commands/picocli/PicocliTestUtils.java @@ -110,7 +110,7 @@ void mockActions() { .thenReturn(actionMock); when(actionsMock.screenshotList(any(), anyBoolean())) .thenReturn(actionMock); - when(actionsMock.screenshotUpload(any(), any(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(), any())) + when(actionsMock.screenshotUpload(any(), any(), any(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(), any())) .thenReturn(actionMock); when(actionsMock.screenshotDelete(any())) .thenReturn(actionMock);