From 5895ecda5c7b70a9167fd693a29e8b67beaa0b10 Mon Sep 17 00:00:00 2001 From: Patrick Huang Date: Tue, 19 May 2015 11:42:37 +1000 Subject: [PATCH] rhbz1215274 - add test for minimum doc percent in pull command --- .../zanata/client/commands/BasicOptions.java | 12 +- .../client/commands/ConfigurableOptions.java | 25 +- .../client/commands/PushPullOptions.java | 4 +- .../client/commands/pull/PullCommandTest.java | 286 ++++++++++++++++++ 4 files changed, 306 insertions(+), 21 deletions(-) create mode 100644 zanata-client-commands/src/test/java/org/zanata/client/commands/pull/PullCommandTest.java diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/BasicOptions.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/BasicOptions.java index 322bd346..3cf317ef 100644 --- a/zanata-client-commands/src/main/java/org/zanata/client/commands/BasicOptions.java +++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/BasicOptions.java @@ -49,9 +49,9 @@ public interface BasicOptions { boolean isQuietSet(); - public boolean isInteractiveMode(); + boolean isInteractiveMode(); - public void setInteractiveMode(boolean interactiveMode); + void setInteractiveMode(boolean interactiveMode); /** * Used to generate the command line interface and its usage help. This name @@ -60,7 +60,7 @@ public interface BasicOptions { * * @return */ - public String getCommandName(); + String getCommandName(); /** * Used to generate CLI usage help. This description should preferably match @@ -68,9 +68,9 @@ public interface BasicOptions { * * @return */ - public String getCommandDescription(); + String getCommandDescription(); - public @Nonnull List getCommandHooks(); + @Nonnull List getCommandHooks(); - public void setCommandHooks(@Nonnull List commandHooks); + void setCommandHooks(@Nonnull List commandHooks); } diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/ConfigurableOptions.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/ConfigurableOptions.java index af94e989..acb688fb 100644 --- a/zanata-client-commands/src/main/java/org/zanata/client/commands/ConfigurableOptions.java +++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/ConfigurableOptions.java @@ -18,37 +18,37 @@ public interface ConfigurableOptions extends BasicOptions { /** * API key for accessing the REST API. Defaults to the value in zanata.ini. */ - public String getKey(); + String getKey(); - public void setKey(String key); + void setKey(String key); /** * Base URL for the server. Defaults to the value in zanata.xml. */ - public URL getUrl(); + URL getUrl(); - public void setUrl(URL url); + void setUrl(URL url); /** * Client configuration file. */ - public File getUserConfig(); + File getUserConfig(); - public void setUserConfig(File userConfig); + void setUserConfig(File userConfig); /** * Username for accessing the REST API. Defaults to the value in zanata.ini. */ - public String getUsername(); + String getUsername(); - public void setUsername(String username); + void setUsername(String username); /** * Enable HTTP message logging. */ - public boolean getLogHttp(); + boolean getLogHttp(); - public void setLogHttp(boolean traceLogging); + void setLogHttp(boolean traceLogging); /** * Disable SSL certificate verification when connecting to Zanata host by @@ -56,13 +56,12 @@ public interface ConfigurableOptions extends BasicOptions { */ boolean isDisableSSLCert(); - public - void setDisableSSLCert(boolean disableSSLCert); + void setDisableSSLCert(boolean disableSSLCert); /** * Use to disable check for presence of username and API key before running command. * * @return true if this command should fail when username or API key is absent. */ - public boolean isAuthRequired(); + boolean isAuthRequired(); } diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/PushPullOptions.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/PushPullOptions.java index dbd8d417..bd0763ab 100644 --- a/zanata-client-commands/src/main/java/org/zanata/client/commands/PushPullOptions.java +++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/PushPullOptions.java @@ -55,7 +55,7 @@ public interface PushPullOptions extends ConfigurableProjectOptions { File getTransDir(); - public String getFromDoc(); + String getFromDoc(); /** * This name should represent the exact parameter as it would be entered on @@ -63,7 +63,7 @@ public interface PushPullOptions extends ConfigurableProjectOptions { * parameter to the argument. This is so that the argument can be appended * directly to the parameter name. */ - public String buildFromDocArgument(String argValue); + String buildFromDocArgument(String argValue); boolean getEnableModules(); diff --git a/zanata-client-commands/src/test/java/org/zanata/client/commands/pull/PullCommandTest.java b/zanata-client-commands/src/test/java/org/zanata/client/commands/pull/PullCommandTest.java new file mode 100644 index 00000000..6d5b8359 --- /dev/null +++ b/zanata-client-commands/src/test/java/org/zanata/client/commands/pull/PullCommandTest.java @@ -0,0 +1,286 @@ +/* + * Copyright 2015, Red Hat, Inc. and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.zanata.client.commands.pull; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.zanata.client.config.LocaleList; +import org.zanata.client.config.LocaleMapping; +import org.zanata.common.LocaleId; +import org.zanata.common.ProjectType; +import org.zanata.common.TransUnitCount; +import org.zanata.rest.StringSet; +import org.zanata.rest.client.RestClientFactory; +import org.zanata.rest.client.SourceDocResourceClient; +import org.zanata.rest.client.StatisticsResourceClient; +import org.zanata.rest.client.TransDocResourceClient; +import org.zanata.rest.dto.resource.Resource; +import org.zanata.rest.dto.stats.ContainerTranslationStatistics; +import org.zanata.rest.dto.stats.TranslationStatistics; + +import com.google.common.collect.Lists; + +public class PullCommandTest { + public static final StringSet EXTENSIONS = new StringSet("comment"); + @Mock + private RestClientFactory restClientFactory; + private PullOptionsImpl opts; + private final String projectSlug = "project"; + private final String versionSlug = "master"; + @Mock + private SourceDocResourceClient sourceClient; + @Mock + private TransDocResourceClient transClient; + @Mock + private StatisticsResourceClient statsClient; + private LocaleList locales; + private PullCommand pullCommand; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + opts = new PullOptionsImpl(); + opts.setProj(projectSlug); + opts.setProjectVersion(versionSlug); + opts.setProjectType(ProjectType.Properties.name().toLowerCase()); + opts.setBatchMode(true); + + when( + restClientFactory.getSourceDocResourceClient(projectSlug, + versionSlug)).thenReturn( + sourceClient); + when(restClientFactory.getTransDocResourceClient(projectSlug, + versionSlug)).thenReturn(transClient); + when(restClientFactory.getStatisticsClient()).thenReturn(statsClient); + + locales = new LocaleList(); + opts.setLocaleMapList(locales); + pullCommand = new PullCommand(opts, restClientFactory); + } + + @Test + public void pullSourceOnlyWillIgnoreMinimumPercent() throws Exception { + locales.add(new LocaleMapping("zh")); + locales.add(new LocaleMapping("de")); + opts.setDryRun(true); + // Given: pull-type is source only and minimum-doc-percent is set to 80 + opts.setPullType("source"); + opts.setMinDocPercent(80); + when(sourceClient + .getResource("file1", EXTENSIONS)).thenReturn( + new Resource()); + pullCommand = new PullCommand(opts, restClientFactory) { + @Override + protected List + getQualifiedDocNamesForCurrentModuleFromServer() { + return Lists.newArrayList("file1"); + } + }; + + // When: + pullCommand.run(); + + // Then: + verifyZeroInteractions(statsClient, transClient); + } + + @Test + public void pullTransOnlyWillIgnoreMinimumPercentIfItIsZero() + throws Exception { + locales.add(new LocaleMapping("zh")); + locales.add(new LocaleMapping("de")); + opts.setDryRun(true); + // Given: pull-type is trans only and minimum-doc-percent is set to 0 + opts.setPullType("trans"); + opts.setMinDocPercent(0); + + pullCommand = new PullCommand(opts, restClientFactory) { + @Override + protected List + getQualifiedDocNamesForCurrentModuleFromServer() { + return Lists.newArrayList("file1"); + } + + @Override + protected void pullDocForLocale(PullStrategy strat, Resource doc, + String localDocName, String docUri, + boolean createSkeletons, + LocaleMapping locMapping, File transFile) + throws IOException { + // pretend we are pulling + transClient.getTranslations(docUri, + new LocaleId(locMapping.getLocale()), EXTENSIONS, + createSkeletons, null); + } + }; + + // When: + pullCommand.run(); + + // Then: + verifyZeroInteractions(statsClient); + verify(transClient).getTranslations("file1", new LocaleId("zh"), + EXTENSIONS, false, + null); + verify(transClient).getTranslations("file1", new LocaleId("de"), + EXTENSIONS, false, + null); + } + + @Test + public void pullTransOnlyWillUseMinimumPercentIfItIsNotZero() + throws Exception { + locales.add(new LocaleMapping("zh")); + locales.add(new LocaleMapping("de")); + opts.setDryRun(true); + // Given: pull-type is trans only and minimum-doc-percent is set to 80 + opts.setPullType("trans"); + opts.setMinDocPercent(80); + + ContainerTranslationStatistics statistics = + new ContainerTranslationStatistics(); + ContainerTranslationStatistics docStats = + new ContainerTranslationStatistics(); + docStats.setId("file1"); + statistics.addDetailedStats(docStats); + // zh has 100 approved + TranslationStatistics zhLocaleStats = + new TranslationStatistics(new TransUnitCount(100, 0, 0, 0, 0), + "zh"); + // de has 39 approved, 21 fuzzy and 40 translated so 79% translated + TranslationStatistics deLocaleStats = + new TranslationStatistics(new TransUnitCount(39, 21, 0, 40, 0), + "de"); + docStats.addStats(zhLocaleStats); + docStats.addStats(deLocaleStats); + + when(statsClient + .getStatistics(projectSlug, versionSlug, true, false, null)) + .thenReturn(statistics); + + pullCommand = new PullCommand(opts, restClientFactory) { + @Override + protected List + getQualifiedDocNamesForCurrentModuleFromServer() { + return Lists.newArrayList("file1"); + } + + @Override + protected void pullDocForLocale(PullStrategy strat, Resource doc, + String localDocName, String docUri, + boolean createSkeletons, + LocaleMapping locMapping, File transFile) + throws IOException { + // pretend we are pulling + transClient.getTranslations(docUri, + new LocaleId(locMapping.getLocale()), EXTENSIONS, + createSkeletons, null); + } + }; + + // When: + pullCommand.run(); + + // Then: translation for "de" will not be pulled + verify(statsClient).getStatistics(projectSlug, versionSlug, true, + false, null); + verify(transClient).getTranslations("file1", new LocaleId("zh"), + EXTENSIONS, false, + null); + verifyNoMoreInteractions(transClient); + } + + @Test + public void whenMinimumPercentIsSetTo100ItWillUseTotalNumber() + throws Exception { + locales.add(new LocaleMapping("zh")); + locales.add(new LocaleMapping("de")); + opts.setDryRun(true); + // Given: pull-type is trans only and minimum-doc-percent is set to 100 + opts.setPullType("trans"); + opts.setMinDocPercent(100); + + ContainerTranslationStatistics statistics = + new ContainerTranslationStatistics(); + ContainerTranslationStatistics docStats = + new ContainerTranslationStatistics(); + docStats.setId("file1"); + statistics.addDetailedStats(docStats); + // zh has 100000 approved + TranslationStatistics zhLocaleStats = + new TranslationStatistics(new TransUnitCount(100000, 0, 0, 0, 0), + "zh"); + // de has 99999 approved, 1 untranslated so 99.999% translated + TranslationStatistics deLocaleStats = + new TranslationStatistics(new TransUnitCount(99999, 0, 1, 0, 0), + "de"); + docStats.addStats(zhLocaleStats); + docStats.addStats(deLocaleStats); + + when(statsClient + .getStatistics(projectSlug, versionSlug, true, false, null)) + .thenReturn(statistics); + + pullCommand = new PullCommand(opts, restClientFactory) { + @Override + protected List + getQualifiedDocNamesForCurrentModuleFromServer() { + return Lists.newArrayList("file1"); + } + + @Override + protected void pullDocForLocale(PullStrategy strat, Resource doc, + String localDocName, String docUri, + boolean createSkeletons, + LocaleMapping locMapping, File transFile) + throws IOException { + // pretend we are pulling + transClient.getTranslations(docUri, + new LocaleId(locMapping.getLocale()), EXTENSIONS, + createSkeletons, null); + } + }; + + // When: + pullCommand.run(); + + // Then: translation for "de" will not be pulled + verify(statsClient).getStatistics(projectSlug, versionSlug, true, + false, null); + verify(transClient).getTranslations("file1", new LocaleId("zh"), + EXTENSIONS, false, + null); + verifyNoMoreInteractions(transClient); + } + +}