Fix CreateLrpTokensCommand to not split lines on double-quoted comma

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=137722530
This commit is contained in:
ctingue 2016-10-31 11:00:24 -07:00 committed by Ben McIlwain
parent 3928ccf03f
commit b29d11f0de
2 changed files with 41 additions and 1 deletions

View file

@ -24,6 +24,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters; import com.beust.jcommander.Parameters;
import com.google.common.base.CharMatcher;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.collect.FluentIterable; import com.google.common.collect.FluentIterable;
@ -96,6 +97,11 @@ public final class CreateLrpTokensCommand implements RemoteApiCommand {
@Inject StringGenerator stringGenerator; @Inject StringGenerator stringGenerator;
private static final int BATCH_SIZE = 20; private static final int BATCH_SIZE = 20;
// Ensures that all of the double quotes to the right of a comma are balanced. In a well-formed
// CSV line, there can be no leading double quote preceding the comma.
private static final String COMMA_EXCEPT_WHEN_QUOTED_REGEX =
",(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)";
@Override @Override
public void run() throws Exception { public void run() throws Exception {
@ -124,7 +130,12 @@ public final class CreateLrpTokensCommand implements RemoteApiCommand {
for (String token : generateTokens(BATCH_SIZE)) { for (String token : generateTokens(BATCH_SIZE)) {
line = reader.readLine(); line = reader.readLine();
if (!isNullOrEmpty(line)) { if (!isNullOrEmpty(line)) {
ImmutableList<String> values = ImmutableList.copyOf(Splitter.on(',').split(line)); ImmutableList<String> values =
ImmutableList.copyOf(
Splitter.onPattern(COMMA_EXCEPT_WHEN_QUOTED_REGEX)
// Results should not be surrounded in double quotes.
.trimResults(CharMatcher.is('\"'))
.split(line));
LrpTokenEntity.Builder tokenBuilder = new LrpTokenEntity.Builder() LrpTokenEntity.Builder tokenBuilder = new LrpTokenEntity.Builder()
.setAssignee(values.get(0)) .setAssignee(values.get(0))
.setToken(token) .setToken(token)

View file

@ -109,6 +109,34 @@ public class CreateLrpTokensCommandTest extends CommandTestCase<CreateLrpTokensC
assertInStdout("domain.tld,LRP_abcdefghijklmnop"); assertInStdout("domain.tld,LRP_abcdefghijklmnop");
} }
@Test
public void testSuccess_oneAssignee_byFile_withMetadata_quotedString() throws Exception {
Files.write("domain.tld,\"foo,foo\",bar", assigneeFile, UTF_8);
runCommand("--input=" + assigneeFilePath, "--tlds=tld", "--metadata_columns=key=1,key2=2");
assertLrpTokens(
createToken(
"LRP_abcdefghijklmnop",
"domain.tld",
ImmutableSet.of("tld"),
null,
ImmutableMap.of("key", "foo,foo", "key2", "bar")));
assertInStdout("domain.tld,LRP_abcdefghijklmnop");
}
@Test
public void testSuccess_oneAssignee_byFile_withMetadata_twoQuotedStrings() throws Exception {
Files.write("domain.tld,\"foo,foo\",\"bar,bar\"", assigneeFile, UTF_8);
runCommand("--input=" + assigneeFilePath, "--tlds=tld", "--metadata_columns=key=1,key2=2");
assertLrpTokens(
createToken(
"LRP_abcdefghijklmnop",
"domain.tld",
ImmutableSet.of("tld"),
null,
ImmutableMap.of("key", "foo,foo", "key2", "bar,bar")));
assertInStdout("domain.tld,LRP_abcdefghijklmnop");
}
@Test @Test
public void testSuccess_emptyFile() throws Exception { public void testSuccess_emptyFile() throws Exception {
Files.write("", assigneeFile, UTF_8); Files.write("", assigneeFile, UTF_8);
@ -235,6 +263,7 @@ public class CreateLrpTokensCommandTest extends CommandTestCase<CreateLrpTokensC
assertThat(match.getValidTlds()).containsExactlyElementsIn(expectedToken.getValidTlds()); assertThat(match.getValidTlds()).containsExactlyElementsIn(expectedToken.getValidTlds());
assertThat(match.getRedemptionHistoryEntry()) assertThat(match.getRedemptionHistoryEntry())
.isEqualTo(expectedToken.getRedemptionHistoryEntry()); .isEqualTo(expectedToken.getRedemptionHistoryEntry());
assertThat(match.getMetadata()).containsExactlyEntriesIn(expectedToken.getMetadata());
} }
} }