Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: label option for string list command #722

Merged
merged 1 commit into from
Feb 8, 2024
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
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);
}
}
}
Loading