Skip to content

Commit

Permalink
feat: label option for string list command (#722)
Browse files Browse the repository at this point in the history
  • Loading branch information
katerina20 authored Feb 8, 2024
1 parent bb57d11 commit 369ef8d
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/main/java/com/crowdin/cli/commands/Actions.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ NewAction<ProjectProperties, ProjectClient> stringEdit(
boolean noProgress, Long id, String identifier, String newText, String newContext, Integer newMaxLength, List<String> labelNames, Boolean isHidden);

NewAction<ProjectProperties, ProjectClient> stringList(
boolean noProgress, boolean isVerbose, String file, String filter, String branchName, String croql);
boolean noProgress, boolean isVerbose, String file, String filter, String branchName, List<String> labelNames, String croql);

NewAction<PropertiesWithFiles, ProjectClient> uploadSources(
String branchName, boolean deleteObsolete, boolean noProgress, boolean autoUpdate, boolean debug, boolean plainView);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ public NewAction<ProjectProperties, ProjectClient> stringEdit(

@Override
public NewAction<ProjectProperties, ProjectClient> stringList(
boolean noProgress, boolean isVerbose, String file, String filter, String branchName, String croql
boolean noProgress, boolean isVerbose, String file, String filter, String branchName, List<String> labelNames, String croql
) {
return new StringListAction(noProgress, isVerbose, file, filter, branchName, croql);
return new StringListAction(noProgress, isVerbose, file, filter, branchName, labelNames, croql);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import static com.crowdin.cli.BaseCli.RESOURCE_BUNDLE;
import static com.crowdin.cli.utils.console.ExecutionStatus.WARNING;
import static java.util.Objects.nonNull;

class StringListAction implements NewAction<ProjectProperties, ProjectClient> {

Expand All @@ -31,14 +32,16 @@ class StringListAction implements NewAction<ProjectProperties, ProjectClient> {
private final String file;
private final String filter;
private final String branchName;
private final List<String> labelNames;
private final String croql;

public StringListAction(boolean noProgress, boolean isVerbose, String file, String filter, String branchName, String croql) {
public StringListAction(boolean noProgress, boolean isVerbose, String file, String filter, String branchName, List<String> labelNames, String croql) {
this.noProgress = noProgress;
this.isVerbose = isVerbose;
this.file = file;
this.filter = filter;
this.branchName = branchName;
this.labelNames = labelNames;
this.croql = croql;
}

Expand All @@ -52,7 +55,8 @@ public void act(Outputter out, ProjectProperties pb, ProjectClient client) {
.map(Branch::getId)
.orElse(null);

Map<Long, String> labels = client.listLabels().stream()
List<Label> labels = client.listLabels();
Map<Long, String> labelsMap = labels.stream()
.collect(Collectors.toMap(Label::getId, Label::getTitle));

Map<String, FileInfo> paths = null;
Expand All @@ -65,28 +69,30 @@ public void act(Outputter out, ProjectProperties pb, ProjectClient client) {
}
Map<Long, String> finalReversePaths = reversePaths;

String encodedFilter = filter != null ? Utils.encodeURL(filter) : null;
String encodedCroql = croql != null ? Utils.encodeURL(croql) : null;
String encodedFilter = nonNull(filter) ? Utils.encodeURL(filter) : null;
String encodedCroql = nonNull(croql) ? Utils.encodeURL(croql) : null;
String labelIds = nonNull(labelNames) ? prepareLabelIds(labels) : null;
String fullPath = nonNull(branchName) ? (branchName + Utils.PATH_SEPARATOR + file) : file;

List<SourceString> sourceStrings;
if (StringUtils.isEmpty(file)) {
sourceStrings = client.listSourceString(null, branchId, null, encodedFilter, encodedCroql);
sourceStrings = client.listSourceString(null, branchId, labelIds, encodedFilter, encodedCroql);
} else {
if (isStringsBasedProject) {
throw new RuntimeException(RESOURCE_BUNDLE.getString("message.no_file_string_project"));
}
if (paths.containsKey(file)) {
sourceStrings = client.listSourceString(paths.get(file).getId(), branchId, null, encodedFilter, encodedCroql);
if (paths.containsKey(fullPath)) {
sourceStrings = client.listSourceString(paths.get(fullPath).getId(), branchId, labelIds, encodedFilter, encodedCroql);
} else {
throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.file_not_exists"), file));
throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.file_not_exists"), fullPath));
}
}
if (sourceStrings.isEmpty()) {
out.println(WARNING.withIcon(RESOURCE_BUNDLE.getString("message.source_string_list_not_found")));
}
sourceStrings.forEach(ss -> {
String labelsString = (ss.getLabelIds() != null)
? ss.getLabelIds().stream().map(labels::get).map(s -> String.format("[@|cyan %s|@]", s)).collect(Collectors.joining(" "))
? ss.getLabelIds().stream().map(labelsMap::get).map(s -> String.format("[@|cyan %s|@]", s)).collect(Collectors.joining(" "))
: "";
out.println(String.format(RESOURCE_BUNDLE.getString("message.source_string_list_text"), ss.getId(), ss.getText(), labelsString));
if (isVerbose) {
Expand All @@ -106,4 +112,14 @@ public void act(Outputter out, ProjectProperties pb, ProjectClient client) {
}
});
}

private String prepareLabelIds(List<Label> labels) {
Map<String, Long> labelsMap = labels.stream()
.collect(Collectors.toMap(Label::getTitle, Label::getId));

return labelNames.stream()
.map(labelsMap::get)
.map(String::valueOf)
.collect(Collectors.joining(","));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class StringListSubcommand extends ActCommandProject {
@CommandLine.Option(names = {"-b", "--branch"}, paramLabel = "...", order = -2)
protected String branchName;

@CommandLine.Option(names = {"--label"}, paramLabel = "...", descriptionKey = "params.label", order = -2)
protected List<String> labelNames;

@CommandLine.Option(names = {"--croql"}, paramLabel = "...", order = -2)
protected String croql;

Expand All @@ -39,6 +42,6 @@ protected List<String> checkOptions() {

@Override
protected NewAction<ProjectProperties, ProjectClient> getAction(Actions actions) {
return actions.stringList(noProgress, isVerbose, file, filter, branchName, croql);
return actions.stringList(noProgress, isVerbose, file, filter, branchName, labelNames, croql);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void testStringEdit() {

@Test
public void testStringList() {
assertNotNull(actions.stringList(false, false, null, null, null, null));
assertNotNull(actions.stringList(false, false, null, null, null, null, null));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.crowdin.cli.properties.PropertiesWithFiles;
import com.crowdin.cli.properties.NewPropertiesWithFilesUtilBuilder;
import com.crowdin.cli.utils.Utils;
import com.crowdin.client.labels.model.Label;
import com.crowdin.client.projectsgroups.model.Type;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
Expand All @@ -22,6 +23,7 @@

import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.params.provider.Arguments.arguments;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
Expand All @@ -35,25 +37,25 @@ public class StringListActionTest {

@ParameterizedTest
@MethodSource
public void testStringList(String file, String filter) throws ResponseException {
public void testStringList(String file, String filter) {
NewPropertiesWithFilesUtilBuilder pbBuilder = NewPropertiesWithFilesUtilBuilder
.minimalBuiltPropertiesBean("*", Utils.PATH_SEPARATOR + "%original_file_name%-CR-%locale%")
.setBasePath(Utils.PATH_SEPARATOR);
pb = pbBuilder.build();
CrowdinProjectFull projectFull = ProjectBuilder.emptyProject(Long.parseLong(pb.getProjectId()))
.addFile("first.csv", "csv", 101L, null, null).build();
CrowdinProjectFull projectFull = ProjectBuilder.emptyProject(Long.parseLong(pb.getProjectId())).addBranches(3L, "main")
.addFile("first.csv", "csv", 101L, null, 3L).build();
projectFull.setType(Type.FILES_BASED);
when(client.downloadFullProject(null))
when(client.downloadFullProject("main"))
.thenReturn(projectFull);
when(client.listSourceString(101L, null, null, filter, null))
.thenReturn(Arrays.asList(SourceStringBuilder.standard()
.setProjectId(Long.parseLong(pb.getProjectId()))
.setIdentifiers(701L, "7-0-1", "seven-o-one", "7.0.1", 101L).build()));

action = new StringListAction(true, true, file, filter, null, null);
action = new StringListAction(true, true, file, filter, "main", null, null);
action.act(Outputter.getDefault(), pb, client);

verify(client).downloadFullProject(null);
verify(client).downloadFullProject(eq("main"));
verify(client).listLabels();
if (file != null) {
verify(client).listSourceString(101L, null, null, filter, null);
Expand All @@ -80,7 +82,7 @@ public void testGetProjectThrows() throws ResponseException {
when(client.downloadFullProject(null))
.thenThrow(new RuntimeException("Whoops"));

action = new StringListAction(true, true, null, null, null, null);
action = new StringListAction(true, true, null, null, null, null, null);
assertThrows(RuntimeException.class, () -> action.act(Outputter.getDefault(), pb, client));

verify(client).downloadFullProject(null);
Expand All @@ -98,7 +100,7 @@ public void testFileNotExistThrows() throws ResponseException {
.thenReturn(ProjectBuilder.emptyProject(Long.parseLong(pb.getProjectId()))
.addFile("first.csv", "csv", 101L, null, null).build());

action = new StringListAction(true, true, "nonexistent.csv", null, null, null);
action = new StringListAction(true, true, "nonexistent.csv", null, null, null, null);
assertThrows(RuntimeException.class, () -> action.act(Outputter.getDefault(), pb, client));

verify(client).downloadFullProject(null);
Expand All @@ -122,12 +124,48 @@ public void testStringList_StringsBasedProject() {
.setProjectId(Long.parseLong(pb.getProjectId()))
.setIdentifiers(701L, "7-0-1", "seven-o-one", "7.0.1", 101L).build()));

action = new StringListAction(true, true, null, null, null, null);
action = new StringListAction(true, true, null, null, null, null, null);
action.act(Outputter.getDefault(), pb, client);

verify(client).downloadFullProject(null);
verify(client).listLabels();
verify(client).listSourceString(null, null, null, null, null);
verifyNoMoreInteractions(client);
}

@Test
public void testStringListLabels() {
NewPropertiesWithFilesUtilBuilder pbBuilder = NewPropertiesWithFilesUtilBuilder
.minimalBuiltPropertiesBean("*", Utils.PATH_SEPARATOR + "%original_file_name%-CR-%locale%")
.setBasePath(Utils.PATH_SEPARATOR);
pb = pbBuilder.build();
CrowdinProjectFull projectFull = ProjectBuilder.emptyProject(Long.parseLong(pb.getProjectId())).addBranches(3L, "main")
.addFile("first.csv", "csv", 101L, null, null).build();
projectFull.setType(Type.FILES_BASED);
Label label1 = new Label() {{
setId(4L);
setTitle("l1");
}};
Label label2 = new Label() {{
setId(5L);
setTitle("l2");
}};

when(client.downloadFullProject(null))
.thenReturn(projectFull);
when(client.listSourceString(101L, null, null, null, null))
.thenReturn(Arrays.asList(SourceStringBuilder.standard()
.setProjectId(Long.parseLong(pb.getProjectId()))
.setIdentifiers(701L, "7-0-1", "seven-o-one", "7.0.1", 101L).build()));
when(client.listLabels()).thenReturn(Arrays.asList(label1, label2));

action = new StringListAction(
true, true, "first.csv", null, null, Arrays.asList("l1", "l2"), null);
action.act(Outputter.getDefault(), pb, client);

verify(client).downloadFullProject(null);
verify(client).listLabels();
verify(client).listSourceString(101L, null, "4,5", null, null);
verifyNoMoreInteractions(client);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void mockActions() {
.thenReturn(actionMock);
when(actionsMock.stringEdit(anyBoolean(), any(), any(), any(), any(), any(), any(), any()))
.thenReturn(actionMock);
when(actionsMock.stringList(anyBoolean(), anyBoolean(), any(), any(), any(), any()))
when(actionsMock.stringList(anyBoolean(), anyBoolean(), any(), any(), any(), any(), any()))
.thenReturn(actionMock);
when(actionsMock.uploadSources(any(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean()))
.thenReturn(actionMock);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ public class StringListSubcommandTest extends PicocliTestUtils {
public void testStringList() {
this.execute(CommandNames.STRING, CommandNames.STRING_LIST);
verify(actionsMock)
.stringList(anyBoolean(), anyBoolean(), any(), any(), any(), any());
.stringList(anyBoolean(), anyBoolean(), any(), any(), any(), any(), any());
this.check(true);
}

@Test
public void testStringList2() {
this.execute(CommandNames.STRING, CommandNames.STRING_LIST, "--file", "some/path/to/file.txt");
verify(actionsMock)
.stringList(anyBoolean(), anyBoolean(), any(), any(), any(), any());
.stringList(anyBoolean(), anyBoolean(), any(), any(), any(), any(), any());
this.check(true);
}
}
}

0 comments on commit 369ef8d

Please sign in to comment.