#293 Add comments to help file, migrate header setting, write tests

This commit is contained in:
ljacqu 2016-10-09 14:53:10 +02:00
parent edfd833198
commit 5928aee097
14 changed files with 294 additions and 60 deletions

View File

@ -12,8 +12,6 @@ import javax.inject.Inject;
import java.util.Collection;
import java.util.List;
import static fr.xephi.authme.settings.properties.PluginSettings.HELP_HEADER;
public class VersionCommand implements ExecutableCommand {
@Inject
@ -25,8 +23,7 @@ public class VersionCommand implements ExecutableCommand {
@Override
public void executeCommand(CommandSender sender, List<String> arguments) {
// Show some version info
sender.sendMessage(ChatColor.GOLD + "==========[ " + commandService.getProperty(HELP_HEADER)
+ " ABOUT ]==========");
sender.sendMessage(ChatColor.GOLD + "==========[ " + AuthMe.getPluginName() + " ABOUT ]==========");
sender.sendMessage(ChatColor.GOLD + "Version: " + ChatColor.WHITE + AuthMe.getPluginName()
+ " v" + AuthMe.getPluginVersion() + ChatColor.GRAY + " (build: " + AuthMe.getPluginBuildNumber() + ")");
sender.sendMessage(ChatColor.GOLD + "Developers:");

View File

@ -6,6 +6,8 @@ package fr.xephi.authme.command.help;
*/
public enum HelpMessage {
HEADER("header"),
OPTIONAL("optional"),
HAS_PERMISSION("hasPermission"),

View File

@ -6,12 +6,10 @@ import fr.xephi.authme.command.CommandArgumentDescription;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandUtils;
import fr.xephi.authme.command.FoundCommandResult;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@ -27,7 +25,7 @@ import static java.util.Collections.singletonList;
/**
* Help syntax generator for AuthMe commands.
*/
public class HelpProvider implements SettingsDependent {
public class HelpProvider implements Reloadable {
// --- Bit flags ---
/** Set to show a command overview. */
@ -50,15 +48,13 @@ public class HelpProvider implements SettingsDependent {
private final PermissionsManager permissionsManager;
private final HelpMessagesService helpMessagesService;
private String helpHeader;
/** int with bit flags set corresponding to the above constants for enabled sections. */
private Integer enabledSections;
@Inject
HelpProvider(PermissionsManager permissionsManager, HelpMessagesService helpMessagesService, Settings settings) {
HelpProvider(PermissionsManager permissionsManager, HelpMessagesService helpMessagesService) {
this.permissionsManager = permissionsManager;
this.helpMessagesService = helpMessagesService;
reload(settings);
}
private List<String> printHelp(CommandSender sender, FoundCommandResult result, int options) {
@ -72,7 +68,10 @@ public class HelpProvider implements SettingsDependent {
// Return directly if no options are enabled so we don't include the help header
return lines;
}
lines.add(ChatColor.GOLD + "==========[ " + helpHeader + " HELP ]==========");
String header = helpMessagesService.getMessage(HelpMessage.HEADER);
if (!header.isEmpty()) {
lines.add(ChatColor.GOLD + header);
}
CommandDescription command = helpMessagesService.buildLocalizedDescription(result.getCommandDescription());
List<String> labels = ImmutableList.copyOf(result.getLabels());
@ -121,8 +120,7 @@ public class HelpProvider implements SettingsDependent {
}
@Override
public void reload(Settings settings) {
helpHeader = settings.getProperty(PluginSettings.HELP_HEADER);
public void reload() {
// We don't know about the reloading order of the classes, i.e. we cannot assume that HelpMessagesService
// has already been reloaded. So set the enabledSections flag to null and redefine it first time needed.
enabledSections = null;

View File

@ -7,9 +7,9 @@ public enum HelpSection {
COMMAND("command"),
SHORT_DESCRIPTION("description.short"),
SHORT_DESCRIPTION("description"),
DETAILED_DESCRIPTION("description.detailed"),
DETAILED_DESCRIPTION("detailedDescription"),
ARGUMENTS("arguments"),

View File

@ -26,7 +26,7 @@ public class MessageFileHandler {
* @param file the file to use for messages
* @param defaultFile the default file from the JAR to use if no message is found
*/
MessageFileHandler(File file, String defaultFile) {
public MessageFileHandler(File file, String defaultFile) {
this.filename = file.getName();
this.configuration = YamlConfiguration.loadConfiguration(file);
this.defaultFile = defaultFile;

View File

@ -49,6 +49,7 @@ public class SettingsMigrationService extends PlainMigrationService {
| migrateJoinLeaveMessages(resource)
| migrateForceSpawnSettings(resource)
| changeBooleanSettingToLogLevelProperty(resource)
| hasOldHelpHeaderProperty(resource)
|| hasDeprecatedProperties(resource);
}
@ -154,6 +155,15 @@ public class SettingsMigrationService extends PlainMigrationService {
return false;
}
private static boolean hasOldHelpHeaderProperty(PropertyResource resource) {
if (resource.contains("settings.helpHeader")) {
ConsoleLogger.warning("Help header setting is now in messages/help_xx.yml, "
+ "please check the file to set it again");
return true;
}
return false;
}
/**
* Checks for an old property path and moves it to a new path if present.
*

View File

@ -9,10 +9,6 @@ import static com.github.authme.configme.properties.PropertyInitializer.newPrope
public class PluginSettings implements SettingsHolder {
@Comment("The name shown in the help messages")
public static final Property<String> HELP_HEADER =
newProperty("settings.helpHeader", "AuthMeReloaded");
@Comment({
"Do you want to enable the session feature?",
"If enabled, when a player authenticates successfully,",

View File

@ -41,8 +41,6 @@ DataSource:
# Column for RealName
mySQLRealName: realname
settings:
# The name shown in the help messages.
helpHeader: AuthMeReloaded
sessions:
# Do you want to enable the session feature?
# If enabled, when a player authenticates successfully,

View File

@ -10,8 +10,8 @@ common:
allowed: 'Allen erlaubt'
section:
command: 'Kommando'
description.short: 'Beschreibung'
description.detailed: 'Detaillierte Beschreibung'
description: 'Beschreibung'
detailedDescription: 'Detaillierte Beschreibung'
arguments: 'Argumente'
permissions: 'Rechte'
alternatives: 'Alternativen'

View File

@ -1,4 +1,9 @@
# Translation config for the AuthMe help, e.g. when /authme help or /authme help register is called
# -------------------------------------------------------
# List of texts used in the help section
common:
header: '==========[ AuthMeReloaded HELP ]=========='
optional: 'Optional'
hasPermission: 'You have permission'
noPermission: 'No permission'
@ -8,14 +13,25 @@ common:
notAllowed: 'No permission'
opOnly: 'OP''s only'
allowed: 'Everyone allowed'
# -------------------------------------------------------
# Titles of the individual help sections
# Set the translation text to empty text to disable the section, e.g. to hide alternatives:
# alternatives: ''
section:
command: 'Command'
description.short: 'Short description'
description.detailed: 'Detailed description'
description: 'Short description'
detailedDescription: 'Detailed description'
arguments: 'Arguments'
permissions: 'Permissions'
alternatives: 'Alternatives'
children: 'Commands'
# -------------------------------------------------------
# You can translate the data for all commands using the below pattern.
# So for example to translate /authme reload, create a section "authme.reload", or "login" for /login
# If the command has arguments, you can use arg1 as below to translate the first argument, and so forth
# Translations don't need to be complete; any missing section will be taken from the default silently
commands:
authme.register:
description: 'Register a player'

View File

@ -0,0 +1,39 @@
package fr.xephi.authme.command.help;
import fr.xephi.authme.util.StringUtils;
import org.junit.Test;
import java.util.HashSet;
import java.util.Set;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
/**
* Test for enums {@link HelpMessage} and {@link HelpSection}.
*/
public class HelpMessageAndHelpSectionConsistencyTest {
@Test
public void shouldHaveUniqueNonEmptyKeys() {
// given
Set<String> keys = new HashSet<>();
// when / then
for (HelpMessage message : HelpMessage.values()) {
assertThat("Key for message '" + message + "' is empty",
StringUtils.isEmpty(message.getKey()), equalTo(false));
if (!keys.add(message.getKey())) {
fail("Key for message '" + message + "' is already used elsewhere");
}
}
for (HelpSection section : HelpSection.values()) {
assertThat("Key for section '" + section + "' is empty",
StringUtils.isEmpty(section.getKey()), equalTo(false));
if (!keys.add(section.getKey())) {
fail("Key for section '" + section + "' is already used elsewhere");
}
}
}
}

View File

@ -0,0 +1,102 @@
package fr.xephi.authme.command.help;
import ch.jalu.injector.testing.BeforeInjecting;
import ch.jalu.injector.testing.DelayedInjectionRunner;
import ch.jalu.injector.testing.InjectDelayed;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.TestCommandsUtil;
import fr.xephi.authme.message.MessageFileHandler;
import fr.xephi.authme.message.MessageFileHandlerProvider;
import fr.xephi.authme.permission.DefaultPermission;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import java.util.Set;
import java.util.function.Function;
import static fr.xephi.authme.TestHelper.getJarFile;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
/**
* Test for {@link HelpMessagesService}.
*/
@RunWith(DelayedInjectionRunner.class)
public class HelpMessagesServiceTest {
private static final String TEST_FILE = "/fr/xephi/authme/command/help/help_test.yml";
private static final Set<CommandDescription> COMMANDS = TestCommandsUtil.generateCommands();
@InjectDelayed
private HelpMessagesService helpMessagesService;
@Mock
private MessageFileHandlerProvider messageFileHandlerProvider;
@BeforeInjecting
public void initializeHandler() {
MessageFileHandler handler = new MessageFileHandler(getJarFile(TEST_FILE), "messages/messages_en.yml");
given(messageFileHandlerProvider.initializeHandler(any(Function.class))).willReturn(handler);
}
@Test
public void shouldReturnLocalizedCommand() {
// given
CommandDescription command = TestCommandsUtil.getCommandWithLabel(COMMANDS, "authme", "register");
// when
CommandDescription localCommand = helpMessagesService.buildLocalizedDescription(command);
// then
assertThat(localCommand.getDescription(), equalTo("Registration"));
assertThat(localCommand.getDetailedDescription(), equalTo("Registers the player"));
assertThat(localCommand.getExecutableCommand(), equalTo(command.getExecutableCommand()));
assertThat(localCommand.getPermission(), equalTo(command.getPermission()));
assertThat(localCommand.getArguments(), hasSize(2));
assertThat(localCommand.getArguments().get(0).getName(), equalTo("password"));
assertThat(localCommand.getArguments().get(0).getDescription(), equalTo("The password"));
assertThat(localCommand.getArguments().get(1).getName(), equalTo("confirmation"));
assertThat(localCommand.getArguments().get(1).getDescription(), equalTo("The confirmation"));
}
@Test
public void shouldReturnLocalizedCommandWithDefaults() {
// given
CommandDescription command = TestCommandsUtil.getCommandWithLabel(COMMANDS, "authme", "login");
// when
CommandDescription localCommand = helpMessagesService.buildLocalizedDescription(command);
// then
assertThat(localCommand.getDescription(), equalTo("Logging in"));
assertThat(localCommand.getDetailedDescription(), equalTo("'login' test command"));
assertThat(localCommand.getArguments(), hasSize(1));
assertThat(localCommand.getArguments().get(0).getName(), equalTo("user password"));
assertThat(localCommand.getArguments().get(0).getDescription(), equalTo("'password' argument description"));
}
@Test
public void shouldReturnSameCommandForNoLocalization() {
// given
CommandDescription command = TestCommandsUtil.getCommandWithLabel(COMMANDS, "email");
// when
CommandDescription localCommand = helpMessagesService.buildLocalizedDescription(command);
// then
assertThat(localCommand, sameInstance(command));
}
@Test
public void shouldGetTranslationsForSectionAndMessage() {
// given / when / then
assertThat(helpMessagesService.getMessage(DefaultPermission.OP_ONLY), equalTo("only op"));
assertThat(helpMessagesService.getMessage(HelpMessage.RESULT), equalTo("res."));
assertThat(helpMessagesService.getMessage(HelpSection.ARGUMENTS), equalTo("arg."));
}
}

View File

@ -10,8 +10,6 @@ import fr.xephi.authme.command.TestCommandsUtil;
import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.junit.BeforeClass;
@ -25,6 +23,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static fr.xephi.authme.command.TestCommandsUtil.getCommandWithLabel;
import static fr.xephi.authme.command.help.HelpProvider.ALL_OPTIONS;
@ -42,8 +41,10 @@ import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
/**
@ -52,7 +53,6 @@ import static org.mockito.Mockito.verify;
@RunWith(DelayedInjectionRunner.class)
public class HelpProviderTest {
private static final String HELP_HEADER = "Help";
private static Set<CommandDescription> commands;
@InjectDelayed
@ -62,8 +62,6 @@ public class HelpProviderTest {
@Mock
private HelpMessagesService helpMessagesService;
@Mock
private Settings settings;
@Mock
private CommandSender sender;
@BeforeClass
@ -73,7 +71,6 @@ public class HelpProviderTest {
@BeforeInjecting
public void setInitialSettings() {
given(settings.getProperty(PluginSettings.HELP_HEADER)).willReturn(HELP_HEADER);
setDefaultHelpMessages(helpMessagesService);
}
@ -89,11 +86,11 @@ public class HelpProviderTest {
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(5));
assertThat(lines.get(0), containsString(HELP_HEADER + " HELP"));
assertThat(removeColors(lines.get(1)), containsString("Command: /authme login <password>"));
assertThat(removeColors(lines.get(2)), containsString("Short description: login cmd"));
assertThat(removeColors(lines.get(3)), equalTo("Detailed description:"));
assertThat(removeColors(lines.get(4)), containsString("'login' test command"));
assertThat(lines.get(0), containsString("Header"));
assertThat(lines.get(1), containsString("Command: /authme login <password>"));
assertThat(lines.get(2), containsString("Short description: login cmd"));
assertThat(lines.get(3), equalTo("Detailed description:"));
assertThat(lines.get(4), containsString("'login' test command"));
}
@Test
@ -108,10 +105,10 @@ public class HelpProviderTest {
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(4));
assertThat(lines.get(0), containsString(HELP_HEADER + " HELP"));
assertThat(removeColors(lines.get(1)), equalTo("Arguments:"));
assertThat(removeColors(lines.get(2)), containsString("password: 'password' argument description"));
assertThat(removeColors(lines.get(3)), containsString("confirmation: 'confirmation' argument description"));
assertThat(lines.get(0), containsString("Header"));
assertThat(lines.get(1), equalTo("Arguments:"));
assertThat(lines.get(2), containsString("password: 'password' argument description"));
assertThat(lines.get(3), containsString("confirmation: 'confirmation' argument description"));
}
@Test
@ -126,7 +123,7 @@ public class HelpProviderTest {
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(3));
assertThat(removeColors(lines.get(2)), containsString("player: 'player' argument description (Optional)"));
assertThat(lines.get(2), containsString("player: 'player' argument description (Optional)"));
}
/** Verifies that the "Arguments:" line is not shown if the command has no arguments. */
@ -159,11 +156,11 @@ public class HelpProviderTest {
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(5));
assertThat(removeColors(lines.get(1)), containsString("Permissions:"));
assertThat(removeColors(lines.get(2)),
assertThat(lines.get(1), containsString("Permissions:"));
assertThat(lines.get(2),
containsString(AdminPermission.UNREGISTER.getNode() + " (Has permission)"));
assertThat(removeColors(lines.get(3)), containsString("Default: Op only (Has permission)"));
assertThat(removeColors(lines.get(4)), containsString("Result: Has permission"));
assertThat(lines.get(3), containsString("Default: Op only (Has permission)"));
assertThat(lines.get(4), containsString("Result: Has permission"));
}
@Test
@ -181,11 +178,11 @@ public class HelpProviderTest {
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(5));
assertThat(removeColors(lines.get(1)), containsString("Permissions:"));
assertThat(removeColors(lines.get(2)),
assertThat(lines.get(1), containsString("Permissions:"));
assertThat(lines.get(2),
containsString(AdminPermission.UNREGISTER.getNode() + " (No permission)"));
assertThat(removeColors(lines.get(3)), containsString("Default: Op only (No permission)"));
assertThat(removeColors(lines.get(4)), containsString("Result: No permission"));
assertThat(lines.get(3), containsString("Default: Op only (No permission)"));
assertThat(lines.get(4), containsString("Result: No permission"));
}
@Test
@ -230,9 +227,9 @@ public class HelpProviderTest {
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(4));
assertThat(removeColors(lines.get(1)), containsString("Alternatives:"));
assertThat(removeColors(lines.get(2)), containsString("/authme register <password> <confirmation>"));
assertThat(removeColors(lines.get(3)), containsString("/authme r <password> <confirmation>"));
assertThat(lines.get(1), containsString("Alternatives:"));
assertThat(lines.get(2), containsString("/authme register <password> <confirmation>"));
assertThat(lines.get(3), containsString("/authme r <password> <confirmation>"));
}
@Test
@ -261,9 +258,9 @@ public class HelpProviderTest {
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(4));
assertThat(removeColors(lines.get(1)), containsString("Children:"));
assertThat(removeColors(lines.get(2)), containsString("/authme login: login cmd"));
assertThat(removeColors(lines.get(3)), containsString("/authme register: register cmd"));
assertThat(lines.get(1), containsString("Children:"));
assertThat(lines.get(2), containsString("/authme login: login cmd"));
assertThat(lines.get(3), containsString("/authme register: register cmd"));
}
@Test
@ -311,8 +308,8 @@ public class HelpProviderTest {
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(2));
assertThat(lines.get(0), containsString(HELP_HEADER + " HELP"));
assertThat(removeColors(lines.get(1)), containsString("Command: /authme register <password> <confirmation>"));
assertThat(lines.get(0), containsString("Header"));
assertThat(lines.get(1), containsString("Command: /authme register <password> <confirmation>"));
}
@Test
@ -341,6 +338,63 @@ public class HelpProviderTest {
assertThat(result, contains("authme", "register"));
}
@Test
public void shouldDisableSectionsWithEmptyTranslations() {
// given
given(helpMessagesService.getMessage(HelpSection.DETAILED_DESCRIPTION)).willReturn("");
given(helpMessagesService.getMessage(HelpSection.ALTERNATIVES)).willReturn("");
given(helpMessagesService.getMessage(HelpSection.PERMISSIONS)).willReturn("");
CommandDescription command = getCommandWithLabel(commands, "authme", "register");
FoundCommandResult result = newFoundResult(command, Collections.singletonList("authme"));
// when
helpProvider.outputHelp(sender, result, ALL_OPTIONS);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(6));
assertThat(lines.get(0), equalTo("Header"));
assertThat(lines.get(1), equalTo("Command: /authme register <password> <confirmation>"));
assertThat(lines.get(2), equalTo("Short description: register cmd"));
assertThat(lines.get(3), equalTo("Arguments:"));
assertThat(lines.get(4), containsString("'password' argument description"));
assertThat(lines.get(5), containsString("'confirmation' argument description"));
}
@Test
public void shouldNotReturnAnythingForAllDisabledSections() {
// given
given(helpMessagesService.getMessage(HelpSection.COMMAND)).willReturn("");
given(helpMessagesService.getMessage(HelpSection.ALTERNATIVES)).willReturn("");
given(helpMessagesService.getMessage(HelpSection.PERMISSIONS)).willReturn("");
CommandDescription command = getCommandWithLabel(commands, "authme", "register");
FoundCommandResult result = newFoundResult(command, Collections.singletonList("authme"));
// when
helpProvider.outputHelp(sender, result, SHOW_COMMAND | SHOW_ALTERNATIVES | SHOW_PERMISSIONS);
// then
verify(sender, never()).sendMessage(anyString());
}
@Test
public void shouldSkipEmptyHeader() {
// given
given(helpMessagesService.getMessage(HelpMessage.HEADER)).willReturn("");
CommandDescription command = getCommandWithLabel(commands, "authme", "register");
FoundCommandResult result = newFoundResult(command, Collections.singletonList("authme"));
// when
helpProvider.outputHelp(sender, result, SHOW_COMMAND);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(1));
assertThat(lines.get(0), equalTo("Command: /authme register <password> <confirmation>"));
}
/**
* Generate an instance of {@link FoundCommandResult} with the given command and labels. All other fields aren't
* retrieved by {@link HelpProvider} and so are initialized to default values for the tests.
@ -363,7 +417,7 @@ public class HelpProviderTest {
private static List<String> getLines(CommandSender sender) {
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(sender, atLeastOnce()).sendMessage(captor.capture());
return captor.getAllValues();
return captor.getAllValues().stream().map(s -> removeColors(s)).collect(Collectors.toList());
}
private static void setDefaultHelpMessages(HelpMessagesService helpMessagesService) {

View File

@ -0,0 +1,22 @@
common:
result: 'res.'
defaultPermissions:
opOnly: 'only op'
section:
arguments: 'arg.'
commands:
authme.register:
description: 'Registration'
detailedDescription: 'Registers the player'
arg1:
label: 'password'
description: 'The password'
arg2:
label: 'confirmation'
description: 'The confirmation'
authme.login:
description: 'Logging in'
arg1:
label: 'user password'