/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.command.internal;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import de.rcenvironment.core.authentication.Session;
import de.rcenvironment.core.command.common.CommandException;
import de.rcenvironment.core.command.internal.handlers.BuiltInCommandPlugin;
import de.rcenvironment.core.utils.common.textstream.TextOutputReceiver;
/**
* Integration test for {@link MultiCommandHandler}. The basic test setup consists of providing mocked/stubbed service dependencies (if
* needed), sending tokenized commands and then verifying the expected output and/or service calls.
*
* @author Robert Mischke
* @author Sascha Zur
* @author Jan Flink
*/
public class MultiCommandHandlerIntegrationTest {
private static final String EXPLAIN_COMMAND_TOKEN = "explain";
private static final String UNEXPECTED_REPONSE_TEXT = "Unexpected reponse text: ";
private CommandPluginDispatcher commandPluginDispatcher;
/**
* Creates a Session for testing.
*/
@BeforeClass
public static void setUpBeforeClass() {
Session.create("dummyUser", 1);
}
/**
* Common test setup.
*/
@Before
public void setUp() {
commandPluginDispatcher = new CommandPluginDispatcher();
commandPluginDispatcher.registerPlugin(new BuiltInCommandPlugin());
}
/**
* Test sending an empty list of tokens. The expected behaviour is an exception that signals that help output should be presented to the
* user.
*/
@Test
public void testEmptyTokenList() {
List<String> tokens = new ArrayList<String>();
TextOutputReceiver outputReceiver = EasyMock.createStrictMock(TextOutputReceiver.class);
// define mock expectation
outputReceiver.onStart();
Capture<CommandException> capture = new Capture<CommandException>();
outputReceiver.onFatalError(EasyMock.capture(capture));
EasyMock.replay(outputReceiver);
// invoke
new MultiCommandHandler(tokens, outputReceiver, commandPluginDispatcher).call();
// test callback parameter(s)
assertEquals("Unexpected CommandException sub-type", CommandException.Type.HELP_REQUESTED, capture.getValue().getType());
EasyMock.verify(outputReceiver);
}
/**
* Test sending the "dummy" command. The expected behaviour is a response line containing the word "dummy" (case insensitive), followed
* by an "end-of-output" marker.
*/
@Test
public void testDummyCommand() {
List<String> tokens = new ArrayList<String>();
tokens.add("dummy");
TextOutputReceiver outputReceiver = EasyMock.createStrictMock(TextOutputReceiver.class);
// define mock expectation
outputReceiver.onStart();
Capture<String> capture = new Capture<String>();
outputReceiver.addOutput(EasyMock.capture(capture));
outputReceiver.onFinished();
EasyMock.replay(outputReceiver);
// invoke
new MultiCommandHandler(tokens, outputReceiver, commandPluginDispatcher).call();
// test callback parameter(s)
String capturedText = capture.getValue();
assertTrue("Unexpected reponse text (should contain 'dummy')", capturedText.toLowerCase().contains("dummy"));
EasyMock.verify(outputReceiver);
}
/**
* Tests whether quoted strings that were split into separate tokens are properly re-assembled, and if empty tokens (resulting from
* multi-whitespace splitting) are properly discarded.
*/
@Test
public void testTokenQuotingNormalization() {
List<String> tokens = Arrays.asList(new String[] {
EXPLAIN_COMMAND_TOKEN, "a", "\"b", "2", "", "", "c\"", "d"
});
String capturedText = runWithTokens(tokens);
assertTrue(UNEXPECTED_REPONSE_TEXT + capturedText, capturedText.toLowerCase().contains("[a, b 2 c, d]"));
}
/**
* Tests if unfinished quoted parts like <code>test "a b c</code> are properly rejected.
*/
@Test
public void testTokenQuotingFailureOnUnfinishedSequence() {
List<String> tokens = Arrays.asList(new String[] {
EXPLAIN_COMMAND_TOKEN, "a", "\"b", "2", "", "", "c\"", "d", "\"start", "addition"
});
String capturedText = runWithTokens(tokens);
assertTrue(UNEXPECTED_REPONSE_TEXT + capturedText, capturedText.toLowerCase().contains("error: "));
assertTrue(UNEXPECTED_REPONSE_TEXT + capturedText, capturedText.toLowerCase().contains(": start addition"));
}
/**
* Tests unusual, but accepted uses of quotes.
*/
@Test
public void testTokenQuotingSpecialCases() {
List<String> tokens = Arrays.asList(new String[] {
EXPLAIN_COMMAND_TOKEN, "a\"b", "\"c", "d\"e", "\"", "f\"g"
});
String capturedText = runWithTokens(tokens);
assertTrue(UNEXPECTED_REPONSE_TEXT + capturedText, capturedText.toLowerCase().contains("[a\"b, c d\"e , f\"g]"));
}
/**
* Tests that escaped double-quotes are properly unescaped.
*/
@Test
public void testTokenQuotesUnescaping() {
List<String> tokens = Arrays.asList(new String[] {
EXPLAIN_COMMAND_TOKEN, "a\\\"", "\\\"b", "c\\\"d"
});
String capturedText = runWithTokens(tokens);
assertTrue(UNEXPECTED_REPONSE_TEXT + capturedText, capturedText.toLowerCase().contains("[a\", \"b, c\"d]"));
}
private String runWithTokens(List<String> tokens) {
TextOutputReceiver outputReceiver = EasyMock.createStrictMock(TextOutputReceiver.class);
// define mock expectation
outputReceiver.onStart();
Capture<String> capture = new Capture<String>();
outputReceiver.addOutput(EasyMock.capture(capture));
outputReceiver.onFinished();
EasyMock.replay(outputReceiver);
// invoke
new MultiCommandHandler(tokens, outputReceiver, commandPluginDispatcher).call();
// test callback parameter(s)
String capturedText = capture.getValue();
EasyMock.verify(outputReceiver);
return capturedText;
}
}