Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
rhbz1110627 - able to filter project in long list
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Huang committed Aug 21, 2014
1 parent a8fa923 commit 85f9c01
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
Expand All @@ -29,7 +30,8 @@ class ProjectPrompt {
projectIterationPrompt;
private final ZanataProxyFactory proxyFactory;
// state variables
private List<Project> projects = Collections.emptyList();
private List<Project> allProjects = Collections.emptyList();
private List<Project> filteredProjects = Collections.emptyList();

ProjectPrompt(Interactiveable interactiveable, InitOptions opts,
ZanataProxyFactory proxyFactory,
Expand Down Expand Up @@ -60,31 +62,68 @@ protected void selectProject() {
interactiveable.printfln(_("available.projects"));
int oneBasedIndex = 1;
List<String> projectIndexes = Lists.newArrayList();
for (Project project : projects) {
for (Project project : filteredProjects) {
projectIndexes.add(oneBasedIndex + "");
interactiveable.printfln("%d) id:%s name:%s", oneBasedIndex,
project.getId(),
project.getName());
oneBasedIndex++;
}
interactiveable.printf(_("select.project.prompt"));
String selection = interactiveable.expectAnswerWithRetry(projectIndexes);
Project project = projects.get(Integer.valueOf(selection) - 1);
String selection = interactiveable.expectAnyAnswer();
if (selectionIsFilter(selection, filteredProjects)) {
filteredProjects = filterBy(selection);
selectProject();
return;
}
Project project = filteredProjects.get(Integer.valueOf(selection) - 1);
String projectId = project.getId();
opts.setProj(projectId);
// TODO server returns Upper case project type!!!
opts.setProjectType(project.getDefaultType().toLowerCase());
projectIterationPrompt.selectOrCreateNewVersion();
}

private boolean selectionIsFilter(String selection,
List<Project> filteredProjects) {
if (selection.matches("\\d+")) {
Integer indexNum = Integer.valueOf(selection) - 1;
// if input is a valid index number
if (indexNum >=0 && indexNum < filteredProjects.size()) {
return false;
}
}
return true;
}

@VisibleForTesting
protected List<Project> filterBy(final String selection) {
if (Strings.isNullOrEmpty(selection)) {
return allProjects;
}
Iterable<Project> filter =
Iterables.filter(filteredProjects, new Predicate<Project>() {
@Override
public boolean apply(Project input) {
String lowerCase = selection.toLowerCase();
return input.getId().toLowerCase()
.contains(lowerCase) ||
input.getName().toLowerCase()
.contains(lowerCase);
}
});
return ImmutableList.copyOf(filter);
}

// we only talk to server once
private void ensureActiveProjects() {
if (projects.isEmpty()) {
if (filteredProjects.isEmpty()) {
// TODO add optional query param to search projects (limit return
// values)
Project[] projectsArray =
proxyFactory.getProjectsResource().get()
.getEntity(Project[].class);
projects = ImmutableList.copyOf(Iterables
allProjects = ImmutableList.copyOf(Iterables
.filter(Lists.newArrayList(projectsArray),
new Predicate<Project>() {
@Override
Expand All @@ -93,9 +132,17 @@ public boolean apply(Project input) {
EntityStatus.ACTIVE;
}
}));
filteredProjects = ImmutableList.copyOf(allProjects);
}
}

@VisibleForTesting
protected void setAllAndFilteredProjects(List<Project> allProjects,
List<Project> filteredProjects) {
this.allProjects = allProjects;
this.filteredProjects = filteredProjects;
}

@VisibleForTesting
protected void createNewProject() {
interactiveable.printfln(_("create.project.help"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ backup.old.project.config=Old project config is renamed to %s

project.select.or.create=Do you want to 1) select an existing project or 2) create a new one (1/2)?
available.projects======== Available project(s): id (name) ======
select.project.prompt=Please select your project (index number):
select.project.prompt=Please select your project (index number) or enter part of the project id/name to filter:
create.project.help=Refer to http://zanata.org/help/projects/create-project/ for help.
project.id.prompt=What project Id do you want to have (must be unique, start and end with letter or number, and contain only letters, numbers, underscores and hyphens):
project.name.prompt=What project name do you want to have:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.util.List;

import org.hamcrest.Matchers;
import org.jboss.resteasy.client.ClientResponse;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
Expand All @@ -28,8 +30,10 @@
import org.zanata.client.commands.MockConsoleInteractiveable;
import org.zanata.client.commands.OptionsUtil;
import org.zanata.rest.client.IProjectResource;
import org.zanata.rest.client.IProjectsResource;
import org.zanata.rest.client.ZanataProxyFactory;
import org.zanata.rest.dto.Project;
import com.google.common.collect.Lists;

public class ProjectPromptTest {
private ProjectPrompt prompt;
Expand Down Expand Up @@ -105,6 +109,64 @@ public void willShowAllActiveProjectsIfUserChooseToSelect()
assertThat(opts.getProjectVersion(), Matchers.equalTo("master"));
}

@Test
public void willFilterAllProjectsIfUserTypeLetters() {
proxyFactory = mock(ZanataProxyFactory.class);

IProjectsResource projectsResource = mock(IProjectsResource.class,
Answers.RETURNS_DEEP_STUBS.get());
when(proxyFactory.getProjectsResource()).thenReturn(projectsResource);
when(projectsResource.get().getEntity(Project[].class))
.thenReturn(new Project[] {
makeProject("project-1", "project one"),
makeProject("project-2", "project two"),
makeProject("project-99", "project 99") });

// Given: user input
Interactiveable console =
MockConsoleInteractiveable.predefineAnswers(
"99", // part of project name
"1");
prompt =
new ProjectPrompt(console, opts, proxyFactory,
mock(ProjectIterationPrompt.class));
prompt.selectProject();

assertThat(opts.getProj(), Matchers.equalTo("project-99"));
assertThat(opts.getProjectType(), Matchers.equalTo("gettext"));
}

private static Project makeProject(String slug, String name) {
Project project = new Project();
project.setId(slug);
project.setName(name);
project.setDefaultType("gettext");
return project;
}

@Test
public void canFilterProject() {
prompt =
new ProjectPrompt(mock(Interactiveable.class), opts,
mock(ZanataProxyFactory.class),
mock(ProjectIterationPrompt.class));

Project gcc = makeProject("gcc", "gnu c compiler");
Project aboutFedora = makeProject("about-fedora", "about fedora");
Project ibus =
makeProject("ibus-pinyin", "ibus pinyin input method");
Project tar = makeProject("gnu-tar", "tar");
List<Project> allProjects =
Lists.newArrayList(gcc, aboutFedora, ibus, tar);
List<Project> filteredProjects =
Lists.newArrayList(gcc, ibus, tar);
prompt.setAllAndFilteredProjects(allProjects, filteredProjects);

assertThat(prompt.filterBy(""), Matchers.equalTo(allProjects));
assertThat(prompt.filterBy("gnu"), Matchers.contains(gcc, tar));
assertThat(prompt.filterBy("bus"), Matchers.contains(ibus));
}

// this test uses mock for REST call and everything.
@Test
public void willGuideUserIfUserChooseToCreateNewProjectAndVersion()
Expand Down

0 comments on commit 85f9c01

Please sign in to comment.