diff --git a/src/main/java/seedu/todo/controllers/ConfigController.java b/src/main/java/seedu/todo/controllers/ConfigController.java index e57db4ab3f97..adcc5f19c377 100644 --- a/src/main/java/seedu/todo/controllers/ConfigController.java +++ b/src/main/java/seedu/todo/controllers/ConfigController.java @@ -1,7 +1,6 @@ package seedu.todo.controllers; import java.io.IOException; -import java.util.List; import seedu.todo.commons.core.Config; import seedu.todo.commons.core.ConfigCenter; @@ -10,12 +9,11 @@ import seedu.todo.models.TodoListDB; import seedu.todo.ui.UiManager; +// @@author A0139812A /** * Controller to configure app settings. * Has side effects, since it has to perform * updates on the UI or file sources on update. - * - * @@author A0139812A */ public class ConfigController extends Controller { @@ -26,12 +24,14 @@ public class ConfigController extends Controller { private static final String MESSAGE_SHOWING = "Showing all settings."; private static final String MESSAGE_SUCCESS = "Successfully updated %s."; - private static final String MESSAGE_FAILURE = "Could not update settings: %s"; + public static final String MESSAGE_FAILURE = "Could not update settings: %s"; private static final String MESSAGE_INVALID_INPUT = "Invalid config setting provided!"; - private static final String MESSAGE_WRONG_EXTENSION = "Could not change storage path: File must end with %s"; - private static final String SPACE = " "; + public static final String MESSAGE_WRONG_EXTENSION = "Could not change storage path: File must end with %s"; + public static final String TEMPLATE_SET_CONFIG = "config "; + + private static final String STRING_SPACE = " "; private static final int ARGS_LENGTH = 2; - private static final String DB_FILE_EXTENSION = ".json"; + public static final String DB_FILE_EXTENSION = ".json"; private static CommandDefinition commandDefinition = new CommandDefinition(NAME, DESCRIPTION, COMMAND_SYNTAX, COMMAND_KEYWORD); @@ -45,58 +45,42 @@ public CommandDefinition getCommandDefinition() { public void process(String input) { String params = input.replaceFirst("config", "").trim(); + // Check for basic command. if (params.length() <= 0) { - - // Showing all configs Renderer.renderConfig(MESSAGE_SHOWING); + return; + } + + // Check args length + String[] args = params.split(STRING_SPACE, ARGS_LENGTH); + if (args.length != ARGS_LENGTH) { + Renderer.renderDisambiguation(TEMPLATE_SET_CONFIG, MESSAGE_INVALID_INPUT); + return; + } + + String configName = args[0]; + String configValue = args[1]; + Config config = ConfigCenter.getInstance().getConfig(); + + // Check if configName is a valid name. + if (!config.getDefinitionsNames().contains(configName)) { + Renderer.renderDisambiguation(TEMPLATE_SET_CONFIG, MESSAGE_INVALID_INPUT); + return; + } - } else { - - String[] args = params.split(SPACE, ARGS_LENGTH); - - // Check args length - if (args.length != ARGS_LENGTH) { - Renderer.renderConfig(MESSAGE_INVALID_INPUT); - return; - } - - assert args.length == ARGS_LENGTH; - - // Split by args - String configName = args[0]; - String configValue = args[1]; - - // Get current config - Config config = ConfigCenter.getInstance().getConfig(); - - // Check name - List validConfigDefinitions = config.getDefinitionsNames(); - if (!validConfigDefinitions.contains(configName)) { - Renderer.renderConfig(MESSAGE_INVALID_INPUT); - return; - } - - assert validConfigDefinitions.contains(configName); - + try { // Update config value - try { - config = updateConfigByName(config, configName, configValue); - } catch (CannotConfigureException e) { - Renderer.renderConfig(e.getMessage()); - return; - } - + config = updateConfigByName(config, configName, configValue); + // Save config to file - try { - ConfigCenter.getInstance().saveConfig(config); - } catch (IOException e) { - Renderer.renderConfig(String.format(MESSAGE_FAILURE, e.getMessage())); - return; - } - - // Update console for success - Renderer.renderConfig(String.format(MESSAGE_SUCCESS, configName)); + ConfigCenter.getInstance().saveConfig(config); + } catch (CannotConfigureException | IOException e) { + Renderer.renderConfig(String.format(MESSAGE_FAILURE, e.getMessage())); + return; } + + // Update console for success + Renderer.renderConfig(String.format(MESSAGE_SUCCESS, configName)); } /** @@ -121,17 +105,8 @@ private Config updateConfigByName(Config config, String configName, String confi break; case "databaseFilePath" : - // Make sure the new path has a .json extension - if (!configValue.endsWith(DB_FILE_EXTENSION)) { - throw new CannotConfigureException(String.format(MESSAGE_WRONG_EXTENSION, DB_FILE_EXTENSION)); - } - // Move the DB file to the new location - try { - TodoListDB.getInstance().move(configValue); - } catch (IOException e) { - throw new CannotConfigureException(e.getMessage()); - } + moveDatabaseFile(configValue); // Update config config.setDatabaseFilePath(configValue); @@ -144,5 +119,22 @@ private Config updateConfigByName(Config config, String configName, String confi return config; } + + /** + * Moves the database file to the new location. + * Throws an exception if the new path does not exist, or if it has the wrong extension. + */ + private void moveDatabaseFile(String newPath) throws CannotConfigureException { + // Make sure the new path has a .json extension + if (!newPath.endsWith(DB_FILE_EXTENSION)) { + throw new CannotConfigureException(String.format(MESSAGE_WRONG_EXTENSION, DB_FILE_EXTENSION)); + } + + try { + TodoListDB.getInstance().move(newPath); + } catch (IOException e) { + throw new CannotConfigureException(e.getMessage()); + } + } } diff --git a/src/main/resources/ui/components/ConfigItem.fxml b/src/main/resources/ui/components/ConfigItem.fxml index 3176a172ac16..e044f8c05e41 100644 --- a/src/main/resources/ui/components/ConfigItem.fxml +++ b/src/main/resources/ui/components/ConfigItem.fxml @@ -6,7 +6,7 @@ - diff --git a/src/test/java/seedu/todo/guitests/ConfigCommandTest.java b/src/test/java/seedu/todo/guitests/ConfigCommandTest.java new file mode 100644 index 000000000000..94247c09b2d0 --- /dev/null +++ b/src/test/java/seedu/todo/guitests/ConfigCommandTest.java @@ -0,0 +1,64 @@ +package seedu.todo.guitests; + +import static org.junit.Assert.*; + +import java.io.File; + +import org.junit.Test; + +import seedu.todo.TestApp; +import seedu.todo.commons.core.ConfigCenter; +import seedu.todo.commons.core.ConfigDefinition; +import seedu.todo.controllers.ConfigController; + +public class ConfigCommandTest extends GuiTest { + + @Test + public void config_showAll_success() { + console.runCommand("config"); + for (ConfigDefinition configDefinition : ConfigCenter.getInstance().getConfig().getDefinitions()) { + assertNotNull(configView.getConfigItem(configDefinition)); + } + } + + @Test + public void config_invalidConfigName_disambig() { + console.runCommand("config invalidConfigName someValue"); + assertEquals(ConfigController.TEMPLATE_SET_CONFIG, console.getConsoleInputText()); + } + + @Test + public void config_tooLittleArgs_disambig() { + console.runCommand("config appTitle"); + assertEquals(ConfigController.TEMPLATE_SET_CONFIG, console.getConsoleInputText()); + } + + @Test + public void config_setAppTitle_success() { + console.runCommand("config appTitle Pokemon Center"); + assertEquals("Pokemon Center", header.getAppTitle()); + assertEquals("Pokemon Center", ConfigCenter.getInstance().getConfig().getAppTitle()); + } + + @Test + public void config_setDatabaseFilePath_success() { + console.runCommand("config databaseFilePath databaseMoved.json"); + assertEquals("databaseMoved.json", ConfigCenter.getInstance().getConfig().getDatabaseFilePath()); + + boolean isFileExists = new File("databaseMoved.json").exists(); + if (isFileExists) { + new File("databaseMoved.json").delete(); + } + + assertTrue(isFileExists); + } + + @Test + public void configDatabaseFilePath_noJsonExtension_error() { + console.runCommand("config databaseFilePath databaseMoved.txt"); + assertEquals(TestApp.SAVE_LOCATION_FOR_TESTING, ConfigCenter.getInstance().getConfig().getDatabaseFilePath()); + assertEquals(String.format(ConfigController.MESSAGE_FAILURE, String.format(ConfigController.MESSAGE_WRONG_EXTENSION, ".json")), + console.getConsoleTextArea()); + } + +} diff --git a/src/test/java/seedu/todo/guitests/GuiTest.java b/src/test/java/seedu/todo/guitests/GuiTest.java index 5f48146600e7..227cb7983d4e 100644 --- a/src/test/java/seedu/todo/guitests/GuiTest.java +++ b/src/test/java/seedu/todo/guitests/GuiTest.java @@ -21,7 +21,9 @@ import seedu.todo.commons.events.BaseEvent; import seedu.todo.commons.util.DateUtil; import seedu.todo.guitests.guihandles.AliasViewHandle; +import seedu.todo.guitests.guihandles.ConfigViewHandle; import seedu.todo.guitests.guihandles.ConsoleHandle; +import seedu.todo.guitests.guihandles.HeaderHandle; import seedu.todo.guitests.guihandles.HelpViewHandle; import seedu.todo.guitests.guihandles.MainGuiHandle; import seedu.todo.guitests.guihandles.TagListHandle; @@ -45,9 +47,11 @@ public abstract class GuiTest { // Handles to GUI elements present at the start up are created in advance for easy access from child classes. protected MainGuiHandle mainGui; protected ConsoleHandle console; + protected HeaderHandle header; protected TaskListHandle taskList; protected TagListHandle tagList; protected AliasViewHandle aliasView; + protected ConfigViewHandle configView; protected HelpViewHandle helpView; private Stage stage; @@ -67,9 +71,11 @@ public void setup() throws Exception { FxToolkit.setupStage((stage) -> { mainGui = new MainGuiHandle(new GuiRobot(), stage); console = mainGui.getConsole(); + header = mainGui.getHeader(); taskList = mainGui.getTaskList(); tagList = mainGui.getTagList(); aliasView = mainGui.getAliasView(); + configView = mainGui.getConfigView(); helpView = mainGui.getHelpView(); // TODO: create handles for other components this.stage = stage; diff --git a/src/test/java/seedu/todo/guitests/guihandles/ConfigItemHandle.java b/src/test/java/seedu/todo/guitests/guihandles/ConfigItemHandle.java new file mode 100644 index 000000000000..a62d3aa4baa0 --- /dev/null +++ b/src/test/java/seedu/todo/guitests/guihandles/ConfigItemHandle.java @@ -0,0 +1,39 @@ +package seedu.todo.guitests.guihandles; + +import javafx.scene.Node; +import javafx.stage.Stage; +import seedu.todo.commons.core.ConfigDefinition; +import seedu.todo.guitests.GuiRobot; + +// @@author A0139812A +public class ConfigItemHandle extends GuiHandle { + + private static final String CONFIG_NAME_TEXT_ID = "#configName"; + private static final String CONFIG_DESC_TEXT_ID = "#configDescription"; + private static final String CONFIG_VALUE_TEXT_ID = "#configValue"; + private Node node; + + public ConfigItemHandle(GuiRobot guiRobot, Stage primaryStage, Node node){ + super(guiRobot, primaryStage, null); + this.node = node; + } + + public String getConfigName() { + return getStringFromText(CONFIG_NAME_TEXT_ID, node); + } + + public String getConfigDescription() { + return getStringFromText(CONFIG_DESC_TEXT_ID, node); + } + + public String getConfigValue() { + return getStringFromText(CONFIG_VALUE_TEXT_ID, node); + } + + public boolean isEqualsTo(ConfigDefinition configDefinition) { + return getConfigName().equals(configDefinition.getConfigName()) + && getConfigDescription().equals(configDefinition.getConfigDescription()) + && getConfigValue().equals(configDefinition.getConfigValue()); + } + +} diff --git a/src/test/java/seedu/todo/guitests/guihandles/ConfigViewHandle.java b/src/test/java/seedu/todo/guitests/guihandles/ConfigViewHandle.java new file mode 100644 index 000000000000..79324af0dec8 --- /dev/null +++ b/src/test/java/seedu/todo/guitests/guihandles/ConfigViewHandle.java @@ -0,0 +1,40 @@ + +package seedu.todo.guitests.guihandles; + +import java.util.Optional; + +import javafx.scene.Node; +import javafx.stage.Stage; +import seedu.todo.commons.core.ConfigDefinition; +import seedu.todo.guitests.GuiRobot; + +// @@author A0139812A +public class ConfigViewHandle extends GuiHandle { + + private static final String CONFIGVIEW_TEXT_ID = "#configInstructionsText"; + private static final String CONFIG_ITEM_ID = "#configItem"; + + public ConfigViewHandle(GuiRobot guiRobot, Stage primaryStage, String stageTitle) { + super(guiRobot, primaryStage, stageTitle); + } + + /** + * Checks for the existence of a child element to determine if the view has loaded correctly. + */ + public boolean hasLoaded() { + return guiRobot.lookup(CONFIGVIEW_TEXT_ID).queryAll().size() > 0; + } + + public ConfigItemHandle getConfigItem(ConfigDefinition configDefinition) { + Optional itemNode = guiRobot.lookup(CONFIG_ITEM_ID).queryAll().stream() + .filter(node -> new ConfigItemHandle(guiRobot, primaryStage, node).isEqualsTo(configDefinition)) + .findFirst(); + + if (itemNode.isPresent()) { + return new ConfigItemHandle(guiRobot, primaryStage, itemNode.get()); + } else { + return null; + } + } + +} diff --git a/src/test/java/seedu/todo/guitests/guihandles/HeaderHandle.java b/src/test/java/seedu/todo/guitests/guihandles/HeaderHandle.java new file mode 100644 index 000000000000..f44e14629cbd --- /dev/null +++ b/src/test/java/seedu/todo/guitests/guihandles/HeaderHandle.java @@ -0,0 +1,18 @@ +package seedu.todo.guitests.guihandles; + +import javafx.stage.Stage; +import seedu.todo.guitests.GuiRobot; + +public class HeaderHandle extends GuiHandle { + + private static final String HEADER_APPTITLE_TEXT_ID = "#headerAppTitle"; + + public HeaderHandle(GuiRobot guiRobot, Stage primaryStage, String stageTitle) { + super(guiRobot, primaryStage, stageTitle); + } + + public String getAppTitle() { + return getStringFromText(HEADER_APPTITLE_TEXT_ID); + } + +} diff --git a/src/test/java/seedu/todo/guitests/guihandles/MainGuiHandle.java b/src/test/java/seedu/todo/guitests/guihandles/MainGuiHandle.java index deffa7bc6c9c..17c66e46dc0d 100644 --- a/src/test/java/seedu/todo/guitests/guihandles/MainGuiHandle.java +++ b/src/test/java/seedu/todo/guitests/guihandles/MainGuiHandle.java @@ -11,6 +11,10 @@ public MainGuiHandle(GuiRobot guiRobot, Stage primaryStage) { super(guiRobot, primaryStage, TestApp.APP_TITLE); } + public HeaderHandle getHeader() { + return new HeaderHandle(guiRobot, primaryStage, TestApp.APP_TITLE); + } + public ConsoleHandle getConsole() { return new ConsoleHandle(guiRobot, primaryStage, TestApp.APP_TITLE); } @@ -19,6 +23,10 @@ public AliasViewHandle getAliasView() { return new AliasViewHandle(guiRobot, primaryStage, TestApp.APP_TITLE); } + public ConfigViewHandle getConfigView() { + return new ConfigViewHandle(guiRobot, primaryStage, TestApp.APP_TITLE); + } + public HelpViewHandle getHelpView() { return new HelpViewHandle(guiRobot, primaryStage, TestApp.APP_TITLE); }