diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AbstractGlobalOptionsCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AbstractGlobalOptionsCmd.java index a3dc6e16f5d..0183eee90fa 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AbstractGlobalOptionsCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AbstractGlobalOptionsCmd.java @@ -4,6 +4,8 @@ import org.jboss.aesh.cl.Option; import org.jboss.aesh.console.command.Command; import org.keycloak.client.registration.cli.aesh.Globals; +import static org.keycloak.client.registration.cli.util.IoUtil.printOut; + /** * @author Marko Strukelj */ @@ -12,11 +14,28 @@ public abstract class AbstractGlobalOptionsCmd implements Command { @Option(shortName = 'x', description = "Print full stack trace when exiting with error", hasValue = false) protected boolean dumpTrace; + @Option(name = "help", description = "Print command specific help", hasValue = false) + protected boolean help; + protected void init(AbstractGlobalOptionsCmd parent) { dumpTrace = parent.dumpTrace; + help = parent.help; } protected void processGlobalOptions() { Globals.dumpTrace = dumpTrace; } + + protected boolean printHelp() { + if (help) { + printOut(help()); + return true; + } + + return false; + } + + protected String help() { + return KcRegCmd.usage(); + } } diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AttrsCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AttrsCmd.java index fb52357232b..958ae27f5cc 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AttrsCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AttrsCmd.java @@ -48,6 +48,9 @@ public class AttrsCmd extends AbstractGlobalOptionsCmd { try { processGlobalOptions(); + if (printHelp()) { + return CommandResult.SUCCESS; + } EndpointType regType = EndpointType.DEFAULT; PrintStream out = commandInvocation.getShell().out(); @@ -120,6 +123,10 @@ public class AttrsCmd extends AbstractGlobalOptionsCmd { } } + protected String help() { + return usage(); + } + public static String usage() { StringWriter sb = new StringWriter(); PrintWriter out = new PrintWriter(sb); diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCmd.java index be9358d5dcf..b4be107159d 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCmd.java @@ -42,7 +42,11 @@ public class ConfigCmd extends AbstractAuthOptionsCmd implements Command { public CommandResult execute(CommandInvocation commandInvocation) throws CommandException, InterruptedException { try { - if (args.size() == 0) { + if (args == null || args.size() == 0) { + if (printHelp()) { + return CommandResult.SUCCESS; + } + throw new RuntimeException("Sub-command required by '" + OsUtil.CMD + " config' - one of: 'credentials', 'truststore', 'initial-token', 'registration-token'"); } @@ -60,8 +64,12 @@ public class ConfigCmd extends AbstractAuthOptionsCmd implements Command { case "registration-token": { return new ConfigRegistrationTokenCmd(this).execute(commandInvocation); } - default: + default: { + if (printHelp()) { + return CommandResult.SUCCESS; + } throw new RuntimeException("Unknown sub-command: " + cmd); + } } } finally { @@ -69,6 +77,10 @@ public class ConfigCmd extends AbstractAuthOptionsCmd implements Command { } } + protected String help() { + return usage(); + } + public static String usage() { StringWriter sb = new StringWriter(); PrintWriter out = new PrintWriter(sb); diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCredentialsCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCredentialsCmd.java index 6d60530d631..4cc050f702e 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCredentialsCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCredentialsCmd.java @@ -69,6 +69,10 @@ public class ConfigCredentialsCmd extends AbstractAuthOptionsCmd implements Comm try { processGlobalOptions(); + if (printHelp()) { + return CommandResult.SUCCESS; + } + return process(commandInvocation); } finally { commandInvocation.stop(); @@ -170,6 +174,10 @@ public class ConfigCredentialsCmd extends AbstractAuthOptionsCmd implements Comm return CommandResult.SUCCESS; } + protected String help() { + return usage(); + } + public static String usage() { StringWriter sb = new StringWriter(); PrintWriter out = new PrintWriter(sb); diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigInitialTokenCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigInitialTokenCmd.java index 5770e33395b..937787ef03c 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigInitialTokenCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigInitialTokenCmd.java @@ -43,6 +43,10 @@ public class ConfigInitialTokenCmd extends AbstractAuthOptionsCmd implements Com @Override public CommandResult execute(CommandInvocation commandInvocation) throws CommandException, InterruptedException { try { + if (printHelp()) { + return CommandResult.SUCCESS; + } + return process(commandInvocation); } finally { commandInvocation.stop(); @@ -130,6 +134,10 @@ public class ConfigInitialTokenCmd extends AbstractAuthOptionsCmd implements Com return CommandResult.SUCCESS; } + protected String help() { + return usage(); + } + public static String usage() { StringWriter sb = new StringWriter(); PrintWriter out = new PrintWriter(sb); diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigRegistrationTokenCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigRegistrationTokenCmd.java index facea57f95f..761affdfa66 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigRegistrationTokenCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigRegistrationTokenCmd.java @@ -40,6 +40,10 @@ public class ConfigRegistrationTokenCmd extends AbstractAuthOptionsCmd implement @Override public CommandResult execute(CommandInvocation commandInvocation) throws CommandException, InterruptedException { try { + if (printHelp()) { + return CommandResult.SUCCESS; + } + return process(commandInvocation); } finally { commandInvocation.stop(); @@ -120,6 +124,10 @@ public class ConfigRegistrationTokenCmd extends AbstractAuthOptionsCmd implement return CommandResult.SUCCESS; } + protected String help() { + return usage(); + } + public static String usage() { StringWriter sb = new StringWriter(); PrintWriter out = new PrintWriter(sb); diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigTruststoreCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigTruststoreCmd.java index 99917f34a65..49d89759bee 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigTruststoreCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigTruststoreCmd.java @@ -40,6 +40,10 @@ public class ConfigTruststoreCmd extends AbstractAuthOptionsCmd implements Comma @Override public CommandResult execute(CommandInvocation commandInvocation) throws CommandException, InterruptedException { try { + if (printHelp()) { + return CommandResult.SUCCESS; + } + return process(commandInvocation); } finally { commandInvocation.stop(); @@ -130,6 +134,9 @@ public class ConfigTruststoreCmd extends AbstractAuthOptionsCmd implements Comma return CommandResult.SUCCESS; } + protected String help() { + return usage(); + } public static String usage() { StringWriter sb = new StringWriter(); diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/CreateCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/CreateCmd.java index 35f18a12736..30008cab7b8 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/CreateCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/CreateCmd.java @@ -102,6 +102,10 @@ public class CreateCmd extends AbstractAuthOptionsCmd implements Command { try { processGlobalOptions(); + if (printHelp()) { + return CommandResult.SUCCESS; + } + if (args != null) { Iterator it = args.iterator(); while (it.hasNext()) { @@ -226,6 +230,10 @@ public class CreateCmd extends AbstractAuthOptionsCmd implements Command { } } + protected String help() { + return usage(); + } + public static String usage() { StringWriter sb = new StringWriter(); PrintWriter out = new PrintWriter(sb); diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/DeleteCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/DeleteCmd.java index 1d6e8172ade..7a0102dcc60 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/DeleteCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/DeleteCmd.java @@ -27,7 +27,6 @@ import org.keycloak.client.registration.cli.util.ParseUtil; import java.io.PrintWriter; import java.io.StringWriter; -import java.util.ArrayList; import java.util.List; import static org.keycloak.client.registration.cli.util.AuthUtil.ensureToken; @@ -46,19 +45,23 @@ import static org.keycloak.client.registration.cli.util.OsUtil.PROMPT; /** * @author Marko Strukelj */ -@CommandDefinition(name = "delete", description = "CLIENT_ID [GLOBAL_OPTIONS]") +@CommandDefinition(name = "delete", description = "CLIENT [GLOBAL_OPTIONS]") public class DeleteCmd extends AbstractAuthOptionsCmd { @Arguments - private List args = new ArrayList<>(); + private List args; @Override public CommandResult execute(CommandInvocation commandInvocation) throws CommandException, InterruptedException { try { processGlobalOptions(); - if (args.isEmpty()) { - throw new RuntimeException("CLIENT_ID not specified"); + if (printHelp()) { + return CommandResult.SUCCESS; + } + + if (args == null || args.isEmpty()) { + throw new RuntimeException("CLIENT not specified"); } if (args.size() > 1) { @@ -68,7 +71,7 @@ public class DeleteCmd extends AbstractAuthOptionsCmd { String clientId = args.get(0); if (clientId.startsWith("-")) { - warnfErr(ParseUtil.CLIENTID_OPTION_WARN, clientId); + warnfErr(ParseUtil.CLIENT_OPTION_WARN, clientId); } String regType = "default"; @@ -110,6 +113,10 @@ public class DeleteCmd extends AbstractAuthOptionsCmd { } } + protected String help() { + return usage(); + } + public static String usage() { StringWriter sb = new StringWriter(); PrintWriter out = new PrintWriter(sb); diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/GetCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/GetCmd.java index 1b6b7ccf0d4..35936415b97 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/GetCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/GetCmd.java @@ -35,7 +35,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; -import java.util.ArrayList; import java.util.List; import static org.keycloak.client.registration.cli.util.AuthUtil.ensureToken; @@ -67,7 +66,7 @@ public class GetCmd extends AbstractAuthOptionsCmd { private String endpoint; @Arguments - private List args = new ArrayList<>(); + private List args; @Override public CommandResult execute(CommandInvocation commandInvocation) throws CommandException, InterruptedException { @@ -75,6 +74,10 @@ public class GetCmd extends AbstractAuthOptionsCmd { try { processGlobalOptions(); + if (printHelp()) { + return CommandResult.SUCCESS; + } + if (args == null || args.isEmpty()) { throw new RuntimeException("CLIENT not specified"); } @@ -88,7 +91,7 @@ public class GetCmd extends AbstractAuthOptionsCmd { if (clientId.startsWith("-")) { - warnfErr(ParseUtil.CLIENTID_OPTION_WARN, clientId); + warnfErr(ParseUtil.CLIENT_OPTION_WARN, clientId); } ConfigData config = loadConfig(); @@ -172,6 +175,10 @@ public class GetCmd extends AbstractAuthOptionsCmd { } } + protected String help() { + return usage(); + } + public static String usage() { StringWriter sb = new StringWriter(); PrintWriter out = new PrintWriter(sb); diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/KcRegCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/KcRegCmd.java index d2b8a857fef..3b513421f31 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/KcRegCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/KcRegCmd.java @@ -87,7 +87,8 @@ public class KcRegCmd extends AbstractGlobalOptionsCmd { out.println(); out.println("Global options:"); out.println(" -x Print full stack trace when exiting with error"); - out.println(" -c, --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)"); + out.println(" --help Print help for specific command"); + out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)"); out.println(); out.println("Commands: "); out.println(" config Set up credentials, and other configuration settings using the config file"); diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateCmd.java index 87ab781289b..f028c465912 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateCmd.java @@ -106,6 +106,10 @@ public class UpdateCmd extends AbstractAuthOptionsCmd { try { processGlobalOptions(); + if (printHelp()) { + return CommandResult.SUCCESS; + } + String clientId = null; if (args != null) { @@ -117,7 +121,7 @@ public class UpdateCmd extends AbstractAuthOptionsCmd { clientId = it.next(); if (clientId.startsWith("-")) { - warnfErr(ParseUtil.CLIENTID_OPTION_WARN, clientId); + warnfErr(ParseUtil.CLIENT_OPTION_WARN, clientId); } while (it.hasNext()) { @@ -334,6 +338,10 @@ public class UpdateCmd extends AbstractAuthOptionsCmd { } } + protected String help() { + return usage(); + } + public static String usage() { StringWriter sb = new StringWriter(); PrintWriter out = new PrintWriter(sb); @@ -348,7 +356,7 @@ public class UpdateCmd extends AbstractAuthOptionsCmd { out.println(); out.println(" Global options:"); out.println(" -x Print full stack trace when exiting with error"); - out.println(" -c, --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)"); + out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)"); out.println(" --truststore PATH Path to a truststore containing trusted certificates"); out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)"); out.println(" --token TOKEN Registration access token to use"); diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateTokenCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateTokenCmd.java index e52f5a2d18e..3255cad75eb 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateTokenCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateTokenCmd.java @@ -32,7 +32,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; -import java.util.ArrayList; import java.util.List; import static org.keycloak.client.registration.cli.util.AuthUtil.ensureToken; @@ -55,7 +54,7 @@ import static org.keycloak.client.registration.cli.util.OsUtil.PROMPT; public class UpdateTokenCmd extends AbstractAuthOptionsCmd { @Arguments - private List args = new ArrayList<>(); + private List args; @Override public CommandResult execute(CommandInvocation commandInvocation) throws CommandException, InterruptedException { @@ -63,14 +62,18 @@ public class UpdateTokenCmd extends AbstractAuthOptionsCmd { try { processGlobalOptions(); - if (args.isEmpty()) { + if (printHelp()) { + return CommandResult.SUCCESS; + } + + if (args == null || args.isEmpty()) { throw new RuntimeException("CLIENT not specified"); } String clientId = args.get(0); if (clientId.startsWith("-")) { - warnfOut(ParseUtil.CLIENTID_OPTION_WARN, clientId); + warnfOut(ParseUtil.CLIENT_OPTION_WARN, clientId); } ConfigData config = loadConfig(); @@ -129,6 +132,10 @@ public class UpdateTokenCmd extends AbstractAuthOptionsCmd { } } + protected String help() { + return usage(); + } + public static String usage() { StringWriter sb = new StringWriter(); PrintWriter out = new PrintWriter(sb); @@ -141,7 +148,7 @@ public class UpdateTokenCmd extends AbstractAuthOptionsCmd { out.println(); out.println(" Global options:"); out.println(" -x Print full stack trace when exiting with error"); - out.println(" -c, --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)"); + out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)"); out.println(" --truststore PATH Path to a truststore containing trusted certificates"); out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)"); out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish"); diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/util/ParseUtil.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/util/ParseUtil.java index 02ed27a6861..8d237dd9879 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/util/ParseUtil.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/util/ParseUtil.java @@ -38,7 +38,7 @@ import static org.keycloak.client.registration.cli.util.ReflectionUtil.setAttrib */ public class ParseUtil { - public static final String CLIENTID_OPTION_WARN = "You're using what looks like an OPTION as CLIENT_ID: %s"; + public static final String CLIENT_OPTION_WARN = "You're using what looks like an OPTION as CLIENT: %s"; public static final String TOKEN_OPTION_WARN = "You're using what looks like an OPTION as TOKEN: %s"; public static String[] shift(String[] args) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegConfigTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegConfigTest.java index bd8fc7c28bd..473fb1deab3 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegConfigTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegConfigTest.java @@ -23,17 +23,17 @@ public class KcRegConfigTest extends AbstractCliTest { try (TempFileResource configFile = new TempFileResource(handler.getConfigFile())) { - // forget --server + // without --server KcRegExec exe = execute("config registration-token --config '" + configFile.getName() + "' "); assertExitCodeAndStreamSizes(exe, 1, 0, 1); Assert.assertEquals("error message", "Required option not specified: --server", exe.stderrLines().get(0)); - // forget --realm + // without --realm exe = execute("config registration-token --config '" + configFile.getName() + "' --server http://localhost:8080/auth"); assertExitCodeAndStreamSizes(exe, 1, 0, 1); Assert.assertEquals("error message", "Required option not specified: --realm", exe.stderrLines().get(0)); - // forget --client + // without --client exe = execute("config registration-token --config '" + configFile.getName() + "' --server http://localhost:8080/auth --realm test"); assertExitCodeAndStreamSizes(exe, 1, 0, 1); Assert.assertEquals("error message", "Required option not specified: --client", exe.stderrLines().get(0)); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTest.java index b4ea4734882..2469880f80d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTest.java @@ -5,6 +5,7 @@ import org.junit.Test; import org.keycloak.client.registration.cli.config.ConfigData; import org.keycloak.client.registration.cli.config.FileConfigHandler; import org.keycloak.client.registration.cli.config.RealmConfigData; +import org.keycloak.client.registration.cli.util.OsUtil; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.testsuite.cli.KcRegExec; import org.keycloak.testsuite.util.TempFileResource; @@ -16,6 +17,7 @@ import java.io.IOException; import java.util.List; import java.util.UUID; +import static org.keycloak.client.registration.cli.util.OsUtil.CMD; import static org.keycloak.client.registration.cli.util.OsUtil.EOL; import static org.keycloak.testsuite.cli.KcRegExec.execute; @@ -27,7 +29,7 @@ public class KcRegTest extends AbstractCliTest { @Test public void testNoArgs() { /* - * Test most basic execution that returns the initial help + * Test (sub)commands without any arguments */ KcRegExec exe = execute(""); @@ -41,6 +43,123 @@ public class KcRegTest extends AbstractCliTest { lines = exe.stderrLines(); Assert.assertTrue("stderr output empty", lines.size() == 0); + + /* + * Test commands without arguments + */ + exe = execute("config"); + assertExitCodeAndStreamSizes(exe, 1, 0, 1); + Assert.assertEquals("error message", + "Sub-command required by '" + OsUtil.CMD + " config' - one of: 'credentials', 'truststore', 'initial-token', 'registration-token'", + exe.stderrLines().get(0)); + + exe = execute("create"); + assertExitCodeAndStreamSizes(exe, 1, 0, 1); + Assert.assertEquals("error message", "No file nor attribute values specified", exe.stderrLines().get(0)); + + exe = execute("get"); + assertExitCodeAndStreamSizes(exe, 1, 0, 1); + Assert.assertEquals("error message", "CLIENT not specified", exe.stderrLines().get(0)); + + exe = execute("update"); + assertExitCodeAndStreamSizes(exe, 1, 0, 1); + Assert.assertEquals("error message", "No file nor attribute values specified", exe.stderrLines().get(0)); + + exe = execute("delete"); + assertExitCodeAndStreamSizes(exe, 1, 0, 1); + Assert.assertEquals("error message", "CLIENT not specified", exe.stderrLines().get(0)); + + exe = execute("attrs"); + Assert.assertEquals("exit code", 0, exe.exitCode()); + Assert.assertTrue("stdout has response", exe.stdoutLines().size() > 10); + Assert.assertEquals("first line", "Attributes for default format:", exe.stdoutLines().get(0)); + + exe = execute("update-token"); + assertExitCodeAndStreamSizes(exe, 1, 0, 1); + Assert.assertEquals("error message", "CLIENT not specified", exe.stderrLines().get(0)); + + exe = execute("help"); + Assert.assertEquals("exitCode == 0", 0, exe.exitCode()); + lines = exe.stdoutLines(); + Assert.assertTrue("stdout output not empty", lines.size() > 0); + Assert.assertEquals("stdout first line", "Keycloak Client Registration CLI", lines.get(0)); + Assert.assertEquals("stdout one but last line", "Use '" + KcRegExec.CMD + " help ' for more information about a given command.", lines.get(lines.size() - 2)); + Assert.assertEquals("stdout last line", "", lines.get(lines.size() - 1)); + } + + @Test + public void testHelpGlobalOption() { + /* + * Test --help for all commands + */ + KcRegExec exe = execute("--help"); + Assert.assertEquals("exit code", 0, exe.exitCode()); + Assert.assertEquals("no stderr", 0, exe.stderrLines().size()); + Assert.assertEquals("stdout first line", "Keycloak Client Registration CLI", exe.stdoutLines().get(0)); + + exe = execute("create --help"); + Assert.assertEquals("exit code", 0, exe.exitCode()); + Assert.assertEquals("no stderr", 0, exe.stderrLines().size()); + Assert.assertEquals("stdout first line", "Usage: " + CMD + " create [ARGUMENTS]", exe.stdoutLines().get(0)); + + exe = execute("get --help"); + Assert.assertEquals("exit code", 0, exe.exitCode()); + Assert.assertEquals("no stderr", 0, exe.stderrLines().size()); + Assert.assertEquals("stdout first line", "Usage: " + CMD + " get CLIENT [ARGUMENTS]", exe.stdoutLines().get(0)); + + exe = execute("update --help"); + Assert.assertEquals("exit code", 0, exe.exitCode()); + Assert.assertEquals("no stderr", 0, exe.stderrLines().size()); + Assert.assertEquals("stdout first line", "Usage: " + CMD + " update CLIENT [ARGUMENTS]", exe.stdoutLines().get(0)); + + exe = execute("delete --help"); + Assert.assertEquals("exit code", 0, exe.exitCode()); + Assert.assertEquals("no stderr", 0, exe.stderrLines().size()); + Assert.assertEquals("stdout first line", "Usage: " + CMD + " delete CLIENT [ARGUMENTS]", exe.stdoutLines().get(0)); + + exe = execute("attrs --help"); + Assert.assertEquals("exit code", 0, exe.exitCode()); + Assert.assertEquals("no stderr", 0, exe.stderrLines().size()); + Assert.assertEquals("stdout first line", "Usage: " + CMD + " attrs [ATTRIBUTE] [ARGUMENTS]", exe.stdoutLines().get(0)); + + exe = execute("update-token --help"); + Assert.assertEquals("exit code", 0, exe.exitCode()); + Assert.assertEquals("no stderr", 0, exe.stderrLines().size()); + Assert.assertEquals("stdout first line", "Usage: " + CMD + " update-token CLIENT [ARGUMENTS]", exe.stdoutLines().get(0)); + + exe = execute("config --help"); + Assert.assertEquals("exit code", 0, exe.exitCode()); + Assert.assertEquals("no stderr", 0, exe.stderrLines().size()); + Assert.assertEquals("stdout first line", "Usage: " + OsUtil.CMD + " config SUB_COMMAND [ARGUMENTS]", exe.stdoutLines().get(0)); + + exe = execute("config credentials --help"); + Assert.assertEquals("exit code", 0, exe.exitCode()); + Assert.assertEquals("no stderr", 0, exe.stderrLines().size()); + Assert.assertEquals("stdout first line", + "Usage: " + CMD + " config credentials --server SERVER_URL --realm REALM [ARGUMENTS]", + exe.stdoutLines().get(0)); + + exe = execute("config initial-token --help"); + Assert.assertEquals("exit code", 0, exe.exitCode()); + Assert.assertEquals("no stderr", 0, exe.stderrLines().size()); + Assert.assertEquals("stdout first line", + "Usage: " + CMD + " config initial-token --server SERVER --realm REALM [--delete | TOKEN] [ARGUMENTS]", + exe.stdoutLines().get(0)); + + exe = execute("config registration-token --help"); + Assert.assertEquals("exit code", 0, exe.exitCode()); + Assert.assertEquals("no stderr", 0, exe.stderrLines().size()); + Assert.assertEquals("stdout first line", + "Usage: " + CMD + " config registration-token --server SERVER --realm REALM --client CLIENT [--delete | TOKEN] [ARGUMENTS]", + exe.stdoutLines().get(0)); + + exe = execute("config truststore --help"); + Assert.assertEquals("exit code", 0, exe.exitCode()); + Assert.assertEquals("no stderr", 0, exe.stderrLines().size()); + Assert.assertEquals("stdout first line", + "Usage: " + CMD + " config truststore [TRUSTSTORE | --delete] [--trustpass PASSWOD] [ARGUMENTS]", + exe.stdoutLines().get(0)); + } @Test