diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md
index a73d952a472..60b8635b067 100644
--- a/docs/DeveloperGuide.md
+++ b/docs/DeveloperGuide.md
@@ -439,7 +439,7 @@ trimmed to `Tester` and calls `AddDeveloperRoleCommand`.
a new developer role if there is no such role.
:exclamation: **Note:**
-Although no changes is made to the address book, but this stage is still committed so that the success command
+Although no changes is made to the address book, this stage is still committed so that the success command
message and tab index switched to can be changed, the currentPointer can also note that there is an action done here.
:exclamation: **Note:**
@@ -488,7 +488,7 @@ trimmed to `Tester` and calls `DeleteDeveloperRoleCommand`.
if `DeveloperRoles#isRemovableRole()` returns true.
:exclamation: **Note:**
-Although no changes is made to the address book, but this stage is still committed so that the success command
+Although no changes is made to the address book, this stage is still committed so that the success command
message and tab index switched to can be changed, the currentPointer can also note that there is an action done here.
The following sequence diagram shows how the Delete-role operation works:
diff --git a/src/main/java/seedu/address/logic/commands/RedoCommand.java b/src/main/java/seedu/address/logic/commands/RedoCommand.java
index d512ffeae36..17efa4b90e6 100644
--- a/src/main/java/seedu/address/logic/commands/RedoCommand.java
+++ b/src/main/java/seedu/address/logic/commands/RedoCommand.java
@@ -21,7 +21,11 @@ public CommandResult execute(Model model) throws CommandException {
model.redoAddressBook(model);
String previousCommand = model.getPreviousCommandForRedo();
TabIndex index = model.getPreviousTabIndexForRedo();
+ handleRoleRedo(previousCommand);
+ return new CommandResult(MESSAGE_SUCCESS + "\n" + previousCommand, index);
+ }
+ private void handleRoleRedo(String previousCommand) {
if (previousCommand.contains("New role for client added: ")) {
ClientRoles.addClientRole(new ClientRoles(previousCommand.substring(27)));
} else if (previousCommand.contains("New role for developer added: ")) {
@@ -31,6 +35,5 @@ public CommandResult execute(Model model) throws CommandException {
} else if (previousCommand.contains("Role for developers deleted: ")) {
DeveloperRoles.deleteDeveloperRole(new DeveloperRoles(previousCommand.substring(29)));
}
- return new CommandResult(MESSAGE_SUCCESS + "\n" + previousCommand, index);
}
}
diff --git a/src/main/java/seedu/address/logic/commands/UndoCommand.java b/src/main/java/seedu/address/logic/commands/UndoCommand.java
index 3cfb932d7eb..faffb39a91a 100644
--- a/src/main/java/seedu/address/logic/commands/UndoCommand.java
+++ b/src/main/java/seedu/address/logic/commands/UndoCommand.java
@@ -31,6 +31,11 @@ public CommandResult execute(Model model) throws CommandException {
String previousCommand = model.getPreviousCommandForUndo();
TabIndex index = model.getPreviousTabIndex();
// check if it is any of the role commands
+ handleRoleUndo(previousCommand);
+ return new CommandResult(MESSAGE_SUCCESS + "\n" + previousCommand, index);
+ }
+
+ private void handleRoleUndo(String previousCommand) {
if (previousCommand.contains("New role for client added: ")) {
ClientRoles.deleteClientRole(new ClientRoles(previousCommand.substring(27)));
} else if (previousCommand.contains("New role for developer added: ")) {
@@ -40,6 +45,5 @@ public CommandResult execute(Model model) throws CommandException {
} else if (previousCommand.contains("Role for developers deleted: ")) {
DeveloperRoles.addDeveloperRole(new DeveloperRoles(previousCommand.substring(29)));
}
- return new CommandResult(MESSAGE_SUCCESS + "\n" + previousCommand, index);
}
}
diff --git a/src/main/java/seedu/address/logic/commands/addroles/AddClientRoleCommand.java b/src/main/java/seedu/address/logic/commands/addroles/AddClientRoleCommand.java
index 2c69a62f41b..8ed119d0467 100644
--- a/src/main/java/seedu/address/logic/commands/addroles/AddClientRoleCommand.java
+++ b/src/main/java/seedu/address/logic/commands/addroles/AddClientRoleCommand.java
@@ -24,7 +24,7 @@ public class AddClientRoleCommand extends Command {
+ "Example: " + PREFIX_ROLE + "Developer ";
public static final String MESSAGE_SUCCESS = "New role for client added: %1$s";
- public static final String MESSAGE_DUPLICATE_DEVELOPER = "This client role already exists in the address book!";
+ public static final String MESSAGE_DUPLICATE_ROLE = "This client role already exists in the address book!";
private final String toAdd;
/**
@@ -49,7 +49,7 @@ public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
if (ClientRoles.isValidRole(toAdd)) {
- throw new CommandException(MESSAGE_DUPLICATE_DEVELOPER);
+ throw new CommandException(MESSAGE_DUPLICATE_ROLE);
}
String successMessage = String.format(MESSAGE_SUCCESS, Messages.format(toAdd));
diff --git a/src/main/java/seedu/address/logic/commands/addroles/AddDeveloperRoleCommand.java b/src/main/java/seedu/address/logic/commands/addroles/AddDeveloperRoleCommand.java
index d733bf1ede2..a0e6d2b1a98 100644
--- a/src/main/java/seedu/address/logic/commands/addroles/AddDeveloperRoleCommand.java
+++ b/src/main/java/seedu/address/logic/commands/addroles/AddDeveloperRoleCommand.java
@@ -25,7 +25,7 @@ public class AddDeveloperRoleCommand extends Command {
+ "Example: " + PREFIX_ROLE + "Developer ";
public static final String MESSAGE_SUCCESS = "New role for developer added: %1$s";
- public static final String MESSAGE_DUPLICATE_DEVELOPER = "This developer role already exists in the address book!";
+ public static final String MESSAGE_DUPLICATE_ROLE = "This developer role already exists in the address book!";
private final String toAdd;
/**
@@ -50,7 +50,7 @@ public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
if (DeveloperRoles.isValidRole(toAdd)) {
- throw new CommandException(MESSAGE_DUPLICATE_DEVELOPER);
+ throw new CommandException(MESSAGE_DUPLICATE_ROLE);
}
String successMessage = String.format(MESSAGE_SUCCESS, Messages.format(toAdd));
diff --git a/src/main/java/seedu/address/model/VersionedAddressBook.java b/src/main/java/seedu/address/model/VersionedAddressBook.java
index 7dad5cdc940..996ab17e9ed 100644
--- a/src/main/java/seedu/address/model/VersionedAddressBook.java
+++ b/src/main/java/seedu/address/model/VersionedAddressBook.java
@@ -137,6 +137,24 @@ public TabIndex getPreviousTabIndexForRedo() {
return tabIndex.get(currentStatePointer - 1);
}
+ /**
+ * Gets the current addressbook.
+ *
+ * @return The tab index from the previous command.
+ */
+ public ReadOnlyAddressBook getCurrentState(int currentStatePointer) {
+ return addressBookStateList.get(currentStatePointer);
+ }
+
+ /**
+ * Gets the current current state pointer.
+ *
+ * @return The tab index from the previous command.
+ */
+ public int getCurrentStatePointer() {
+ return currentStatePointer;
+ }
+
/**
* Changes the current model's address book to match the current state.
*
diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java
index acc62cbf728..c5746babdfd 100644
--- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java
+++ b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java
@@ -305,7 +305,7 @@ public static void showClientAtIndex(Model model, Index targetIndex) {
}
/**
- * Updates {@code model}'s filtered list to show only the project at the given {@code targetIndex} in the
+ * Updates {@code model}'s filtered list to show only the client at the given {@code targetIndex} in the
* {@code model}'s address book.
*/
public static void showProjectAtIndex(Model model, Index targetIndex) {
@@ -314,6 +314,7 @@ public static void showProjectAtIndex(Model model, Index targetIndex) {
Project project = model.getFilteredProjectList().get(targetIndex.getZeroBased());
final String[] splitName = project.getName().split("\\s+");
model.updateFilteredProjectList(new ProjectNameContainsKeywordsPredicate(Arrays.asList(splitName[0])));
+ assertEquals(4, model.getFilteredProjectList().size());
}
}
diff --git a/src/test/java/seedu/address/logic/commands/RedoCommandTest.java b/src/test/java/seedu/address/logic/commands/RedoCommandTest.java
new file mode 100644
index 00000000000..4b62b132fc6
--- /dev/null
+++ b/src/test/java/seedu/address/logic/commands/RedoCommandTest.java
@@ -0,0 +1,103 @@
+package seedu.address.logic.commands;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.address.testutil.TypicalClients.getTypicalAddressBook;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.ModelManager;
+import seedu.address.model.UserPrefs;
+import seedu.address.model.client.ClientRoles;
+import seedu.address.model.developer.DeveloperRoles;
+import seedu.address.testutil.ClientBuilder;
+
+public class RedoCommandTest {
+
+ private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private Model modelAfterChange = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private RedoCommand redoCommand = new RedoCommand();
+ private UndoCommand undoCommand = new UndoCommand();
+
+ @Test
+ public void execute_validRedo_success() throws CommandException {
+ ClientBuilder clientBuilder = new ClientBuilder();
+ model.addClient(clientBuilder.build());
+ model.commitAddressBook(model, "Add Benson", TabIndex.Client);
+ model.undoAddressBook(model);
+
+ modelAfterChange = model;
+
+ redoCommand.execute(model);
+
+ assertEquals(model, modelAfterChange); // Ensure that the redo was successful
+ }
+
+ @Test
+ public void execute_noRedoAvailable_throwsCommandException() {
+ assertThrows(CommandException.class, () -> redoCommand.execute(model));
+ }
+
+ @Test
+ public void execute_redoRoleCommand_success() throws CommandException {
+ // Undo a command that added a new role for a client
+ ClientRoles.addClientRole(new ClientRoles("NewRole"));
+ model.commitAddressBook(model, "New role for client added: NewRole", TabIndex.Client);
+ undoCommand.execute(model);
+
+ // Redo the role addition
+ redoCommand.execute(model);
+
+ assertTrue(ClientRoles.isValidRole("NewRole"));
+ ClientRoles.deleteClientRole(new ClientRoles("NewRole"));
+ }
+
+ @Test
+ public void execute_redoDeveloperRoleCommand_success() throws CommandException {
+ // Undo a command that added a new role for a developer
+ DeveloperRoles.addDeveloperRole(new DeveloperRoles("NewRole"));
+ model.commitAddressBook(model, "New role for developer added: NewRole", TabIndex.Developer);
+ undoCommand.execute(model);
+
+ // Redo the role addition
+ redoCommand.execute(model);
+ assertTrue(DeveloperRoles.isValidRole("NewRole"));
+ DeveloperRoles.deleteDeveloperRole(new DeveloperRoles("NewRole"));
+ }
+
+ @Test
+ public void execute_redoDeleteClientRoleCommand_success() throws CommandException {
+ ClientRoles.addClientRole(new ClientRoles("RoleToDelete"));
+ model.commitAddressBook(model, "New role for client added: RoleToDelete", TabIndex.Client);
+
+ // Undo a command that deleted a role for a client
+ ClientRoles.deleteClientRole(new ClientRoles("RoleToDelete"));
+ model.commitAddressBook(model, "Role for clients deleted: RoleToDelete", TabIndex.Client);
+ undoCommand.execute(model);
+
+ // Redo the role deletion
+ redoCommand.execute(model);
+
+ assertFalse(ClientRoles.isValidRole("RoleToDelete"));
+ }
+
+ @Test
+ public void execute_redoDeleteDeveloperRoleCommand_success() throws CommandException {
+ DeveloperRoles.addDeveloperRole(new DeveloperRoles("RoleToDelete"));
+ model.commitAddressBook(model, "New role for developer added: NewRole", TabIndex.Developer);
+
+ // Undo a command that deleted a role for a developer
+ DeveloperRoles.deleteDeveloperRole(new DeveloperRoles("RoleToDelete"));
+ model.commitAddressBook(model, "Role for developers deleted: RoleToDelete", TabIndex.Developer);
+ undoCommand.execute(model);
+
+ // Redo the role deletion
+ redoCommand.execute(model);
+
+ assertFalse(DeveloperRoles.isValidRole("RoleToDelete"));
+ }
+}
diff --git a/src/test/java/seedu/address/logic/commands/UndoCommandTest.java b/src/test/java/seedu/address/logic/commands/UndoCommandTest.java
new file mode 100644
index 00000000000..6fa32d885b2
--- /dev/null
+++ b/src/test/java/seedu/address/logic/commands/UndoCommandTest.java
@@ -0,0 +1,121 @@
+package seedu.address.logic.commands;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.address.testutil.TypicalClients.BOB;
+import static seedu.address.testutil.TypicalClients.getTypicalAddressBook;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.ModelManager;
+import seedu.address.model.UserPrefs;
+import seedu.address.model.client.ClientRoles;
+import seedu.address.model.developer.DeveloperRoles;
+import seedu.address.testutil.ClientBuilder;
+import seedu.address.testutil.DeveloperBuilder;
+
+public class UndoCommandTest {
+
+ private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private Model modelAfterChange = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private UndoCommand undoCommand = new UndoCommand();
+
+ @Test
+ public void execute_validUndo_success() throws CommandException {
+ model.addClient(BOB);
+ model.commitAddressBook(model, "Add Alice", TabIndex.Client);
+ undoCommand.execute(model);
+ assertEquals(model, modelAfterChange);
+ }
+
+ @Test
+ public void execute_noUndoAvailable_throwsCommandException() {
+ assertThrows(CommandException.class, () -> undoCommand.execute(model));
+ }
+
+ @Test
+ public void execute_undoNonRoleCommand_success() throws CommandException {
+ // Add a new role for a client
+ ClientBuilder clientBuilder = new ClientBuilder();
+ model.addClient(clientBuilder.build());
+ model.commitAddressBook(model, "New client added", TabIndex.Client);
+
+ // Undo the role addition
+ undoCommand.execute(model);
+
+ assertFalse(model.getFilteredClientList().contains(clientBuilder.build()));
+ }
+
+ @Test
+ public void execute_undoClientRoleCommand_success() throws CommandException {
+ // Add a new role for a client
+ ClientRoles.addClientRole(new ClientRoles("NewRole"));
+ model.commitAddressBook(model, "New role for client added: NewRole", TabIndex.Client);
+
+ // Undo the role addition
+ undoCommand.execute(model);
+
+ assertFalse(ClientRoles.isValidRole("NewRole"));
+ }
+
+ @Test
+ public void execute_undoNonDeveloperRoleCommand_success() throws CommandException {
+ // Add a new role for a client
+ DeveloperBuilder developerBuilder = new DeveloperBuilder();
+ model.addDeveloper(developerBuilder.build());
+ model.commitAddressBook(model, "New Developer Added", TabIndex.Developer);
+
+ // Undo the role addition
+ undoCommand.execute(model);
+
+ assertFalse(model.getFilteredClientList().contains(developerBuilder.build()));
+ }
+
+ @Test
+ public void execute_undoDeveloperRoleCommand_success() throws CommandException {
+ // Add a new role for a client
+ DeveloperRoles.addDeveloperRole(new DeveloperRoles("NewRole"));
+ model.commitAddressBook(model, "New role for developer added: NewRole", TabIndex.Developer);
+
+ // Undo the role addition
+ undoCommand.execute(model);
+
+ assertFalse(DeveloperRoles.isValidRole("NewRole"));
+ }
+
+ @Test
+ public void execute_undoDeleteClientRoleCommand_success() throws CommandException {
+ ClientRoles.addClientRole(new ClientRoles("NewRole"));
+ model.commitAddressBook(model, "New role for client added: NewRole", TabIndex.Client);
+
+ // Delete a role for a client
+ ClientRoles.deleteClientRole(new ClientRoles("NewRole"));
+ model.commitAddressBook(model, "Role for clients deleted: NewRole", TabIndex.Client);
+
+ // Undo the role deletion
+ undoCommand.execute(model);
+
+ assertTrue(ClientRoles.isValidRole("NewRole"));
+ ClientRoles.deleteClientRole(new ClientRoles("NewRole"));
+ }
+
+ @Test
+ public void execute_undoDeleteDeveloperRoleCommand_success() throws CommandException {
+ DeveloperRoles.addDeveloperRole(new DeveloperRoles("RoleToDelete"));
+ model.commitAddressBook(model, "New role for client added: NewRole", TabIndex.Developer);
+
+ // Delete a role for a developer
+ DeveloperRoles.deleteDeveloperRole(new DeveloperRoles("RoleToDelete"));
+ model.commitAddressBook(model, "Role for developers deleted: RoleToDelete", TabIndex.Developer);
+
+ // Undo the role deletion
+ undoCommand.execute(model);
+
+ assertTrue(DeveloperRoles.isValidRole("RoleToDelete"));
+ DeveloperRoles.deleteDeveloperRole(new DeveloperRoles("RoleToDelete"));
+ }
+}
diff --git a/src/test/java/seedu/address/logic/commands/addroles/AddClientRoleCommandTest.java b/src/test/java/seedu/address/logic/commands/addroles/AddClientRoleCommandTest.java
new file mode 100644
index 00000000000..30d5e67ff58
--- /dev/null
+++ b/src/test/java/seedu/address/logic/commands/addroles/AddClientRoleCommandTest.java
@@ -0,0 +1,77 @@
+package seedu.address.logic.commands.addroles;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
+import static seedu.address.testutil.TypicalClients.getTypicalAddressBook;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.logic.commands.deleteroles.DeleteClientRoleCommand;
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.ModelManager;
+import seedu.address.model.UserPrefs;
+import seedu.address.testutil.Assert;
+
+public class AddClientRoleCommandTest {
+
+ private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+
+ @Test
+ public void constructor_nullRole_throwsNullPointerException() {
+ Assert.assertThrows(NullPointerException.class, () -> new AddClientRoleCommand(null));
+ }
+
+ @Test
+ public void execute_roleAcceptedByModel_addSuccessful() throws CommandException {
+ String validRole1 = "Tester";
+ AddClientRoleCommand addClientRoleCommand = new AddClientRoleCommand(validRole1);
+ String expectedMessage = String.format(AddClientRoleCommand.MESSAGE_SUCCESS, validRole1);
+
+ assertEquals(addClientRoleCommand.execute(model).getFeedbackToUser(), expectedMessage);
+
+ DeleteClientRoleCommand deleteClientRoleCommand = new DeleteClientRoleCommand(validRole1);
+ deleteClientRoleCommand.execute(model);
+ }
+
+ @Test
+ public void execute_duplicateRole_throwsCommandException() {
+ String duplicateRole = "Developer";
+ AddClientRoleCommand addClientRoleCommand = new AddClientRoleCommand(duplicateRole);
+
+ assertCommandFailure(addClientRoleCommand, model, AddClientRoleCommand.MESSAGE_DUPLICATE_ROLE);
+ }
+
+ @Test
+ public void equals() {
+ String firstRole = "Tester";
+ String secondRole = "Developer";
+ AddClientRoleCommand addFirstCommand = new AddClientRoleCommand(firstRole);
+ AddClientRoleCommand addSecondCommand = new AddClientRoleCommand(secondRole);
+
+ // same object -> returns true
+ assertTrue(addFirstCommand.equals(addFirstCommand));
+
+ // same values -> returns False because cannot add twice
+ AddClientRoleCommand addFirstCommandCopy = new AddClientRoleCommand(firstRole);
+ assertFalse(addFirstCommand.equals(addFirstCommandCopy));
+
+ // different types -> returns false
+ assertFalse(addFirstCommand.equals(1));
+
+ // null -> returns false
+ assertFalse(addFirstCommand.equals(null));
+
+ // different developer role -> returns false
+ assertFalse(addFirstCommand.equals(addSecondCommand));
+ }
+
+ @Test
+ public void toStringTest() {
+ String roleName = "Tester";
+ AddClientRoleCommand addClientRoleCommand = new AddClientRoleCommand(roleName);
+ assertEquals(addClientRoleCommand.toString(), new AddClientRoleCommand(roleName).toString());
+ }
+}
diff --git a/src/test/java/seedu/address/logic/commands/addroles/AddDeveloperRoleCommandTest.java b/src/test/java/seedu/address/logic/commands/addroles/AddDeveloperRoleCommandTest.java
new file mode 100644
index 00000000000..655ea04bbdc
--- /dev/null
+++ b/src/test/java/seedu/address/logic/commands/addroles/AddDeveloperRoleCommandTest.java
@@ -0,0 +1,79 @@
+package seedu.address.logic.commands.addroles;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
+import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.address.testutil.TypicalDevelopers.getTypicalAddressBook;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.logic.commands.deleteroles.DeleteDeveloperRoleCommand;
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.ModelManager;
+import seedu.address.model.UserPrefs;
+import seedu.address.testutil.Assert;
+
+public class AddDeveloperRoleCommandTest {
+
+ private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private final Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+
+ @Test
+ public void constructor_nullRole_throwsNullPointerException() {
+ Assert.assertThrows(NullPointerException.class, () -> new AddDeveloperRoleCommand(null));
+ }
+
+ @Test
+ public void execute_roleAcceptedByModel_addSuccessful() throws CommandException {
+ String validRole1 = "Tester";
+ AddDeveloperRoleCommand addDeveloperRoleCommand = new AddDeveloperRoleCommand(validRole1);
+ String expectedMessage = String.format(AddDeveloperRoleCommand.MESSAGE_SUCCESS, validRole1);
+
+ assertCommandSuccess(addDeveloperRoleCommand, model, expectedMessage, expectedModel);
+
+ DeleteDeveloperRoleCommand deleteDeveloperRoleCommand = new DeleteDeveloperRoleCommand(validRole1);
+ deleteDeveloperRoleCommand.execute(model);
+ }
+
+ @Test
+ public void execute_duplicateRole_throwsCommandException() {
+ String duplicateRole = "Developer";
+ AddDeveloperRoleCommand addDeveloperRoleCommand = new AddDeveloperRoleCommand(duplicateRole);
+
+ assertCommandFailure(addDeveloperRoleCommand, model, AddDeveloperRoleCommand.MESSAGE_DUPLICATE_ROLE);
+ }
+
+ @Test
+ public void equals() {
+ String firstRole = "Tester";
+ String secondRole = "Developer";
+ AddDeveloperRoleCommand addFirstCommand = new AddDeveloperRoleCommand(firstRole);
+ AddDeveloperRoleCommand addSecondCommand = new AddDeveloperRoleCommand(secondRole);
+
+ // same object -> returns true
+ assertTrue(addFirstCommand.equals(addFirstCommand));
+
+ // same values -> returns False because cannot add twice
+ AddDeveloperRoleCommand addFirstCommandCopy = new AddDeveloperRoleCommand(firstRole);
+ assertFalse(addFirstCommand.equals(addFirstCommandCopy));
+
+ // different types -> returns false
+ assertFalse(addFirstCommand.equals(1));
+
+ // null -> returns false
+ assertFalse(addFirstCommand.equals(null));
+
+ // different developer role -> returns false
+ assertFalse(addFirstCommand.equals(addSecondCommand));
+ }
+
+ @Test
+ public void toStringTest() {
+ String roleName = "Tester";
+ AddDeveloperRoleCommand addDeveloperRoleCommand = new AddDeveloperRoleCommand(roleName);
+ assertEquals(addDeveloperRoleCommand.toString(), new AddDeveloperRoleCommand(roleName).toString());
+ }
+}
diff --git a/src/test/java/seedu/address/logic/commands/deleteroles/DeleteClientRoleCommandTest.java b/src/test/java/seedu/address/logic/commands/deleteroles/DeleteClientRoleCommandTest.java
new file mode 100644
index 00000000000..913575056a8
--- /dev/null
+++ b/src/test/java/seedu/address/logic/commands/deleteroles/DeleteClientRoleCommandTest.java
@@ -0,0 +1,114 @@
+package seedu.address.logic.commands.deleteroles;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
+import static seedu.address.testutil.TypicalDevelopers.getTypicalAddressBook;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.logic.Messages;
+import seedu.address.logic.commands.addroles.AddClientRoleCommand;
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.ModelManager;
+import seedu.address.model.UserPrefs;
+import seedu.address.model.client.ClientRoles;
+import seedu.address.testutil.Assert;
+import seedu.address.testutil.ClientBuilder;
+
+public class DeleteClientRoleCommandTest {
+
+ private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+
+ @Test
+ public void constructor_nullRole_throwsNullPointerException() {
+ Assert.assertThrows(NullPointerException.class, () -> new DeleteClientRoleCommand(null));
+ }
+
+ @Test
+ public void execute_roleAcceptedByModel_deleteSuccessful() throws CommandException {
+
+ String validRole = "NewRole";
+ AddClientRoleCommand addClientRoleCommand = new AddClientRoleCommand(validRole);
+ addClientRoleCommand.execute(model);
+
+ DeleteClientRoleCommand deleteClientRoleCommand = new DeleteClientRoleCommand(validRole);
+
+ String expectedMessage = String.format(DeleteClientRoleCommand.MESSAGE_SUCCESS, validRole);
+ assertEquals(deleteClientRoleCommand.execute(model).getFeedbackToUser(), expectedMessage);
+ }
+
+ @Test
+ public void execute_roleSomeoneUsing_throwsCommandException() throws CommandException {
+ // Assign a client with the specified role
+ String roleWithClient = "NewRole";
+ AddClientRoleCommand addClientRoleCommand = new AddClientRoleCommand(roleWithClient);
+ addClientRoleCommand.execute(model);
+ ClientBuilder clientBuilder = new ClientBuilder().withRole(roleWithClient);
+ model.addClient(clientBuilder.build());
+
+ // Attempt to delete the role
+ DeleteClientRoleCommand deleteClientRoleCommand = new DeleteClientRoleCommand(roleWithClient);
+ String expectedResult = String.format(DeleteClientRoleCommand.MESSAGE_CANNOT_DELETE_REPEAT,
+ Messages.format(roleWithClient));
+
+ // Assert that the command throws an exception
+ assertCommandFailure(deleteClientRoleCommand, model, expectedResult);
+
+ model.deleteClient(clientBuilder.build());
+ deleteClientRoleCommand.execute(model);
+ }
+
+
+ @Test
+ public void execute_roleNotInList_throwsCommandException() {
+ String nonExistingRole = "NonExistingRole";
+ DeleteClientRoleCommand deleteClientRoleCommand = new DeleteClientRoleCommand(nonExistingRole);
+
+ assertCommandFailure(deleteClientRoleCommand, model,
+ DeleteClientRoleCommand.MESSAGE_CANNOT_DELETE_NONEXISTING
+ + DeleteClientRoleCommand.MESSAGE_EXISTING_CLIENT_ROLES
+ + ClientRoles.printRoles());
+ }
+
+ @Test
+ public void execute_roleIsPredefined_throwsCommandException() {
+ String roleWithClient = "Client";
+ DeleteClientRoleCommand deleteClientRoleCommand = new DeleteClientRoleCommand(roleWithClient);
+ assertThrows(CommandException.class, () -> deleteClientRoleCommand.execute(model));
+ }
+
+ @Test
+ public void equals() {
+ String firstRole = "Tester";
+ String secondRole = "Client";
+ DeleteClientRoleCommand deleteFirstCommand = new DeleteClientRoleCommand(firstRole);
+ DeleteClientRoleCommand deleteSecondCommand = new DeleteClientRoleCommand(secondRole);
+
+ // same object -> returns true
+ assertTrue(deleteFirstCommand.equals(deleteFirstCommand));
+
+ // role will no longer exists-> returns false
+ DeleteClientRoleCommand deleteFirstCommandCopy = new DeleteClientRoleCommand(firstRole);
+ assertFalse(deleteFirstCommand.equals(deleteFirstCommandCopy));
+
+ // different types -> returns false
+ assertFalse(deleteFirstCommand.equals(1));
+
+ // null -> returns false
+ assertFalse(deleteFirstCommand.equals(null));
+
+ // different client role -> returns false
+ assertFalse(deleteFirstCommand.equals(deleteSecondCommand));
+ }
+
+ @Test
+ public void toStringTest() {
+ String roleName = "Tester";
+ DeleteClientRoleCommand deleteClientRoleCommand = new DeleteClientRoleCommand(roleName);
+ assertEquals(deleteClientRoleCommand.toString(), new DeleteClientRoleCommand(roleName).toString());
+ }
+}
diff --git a/src/test/java/seedu/address/logic/commands/deleteroles/DeleteDeveloperRoleCommandTest.java b/src/test/java/seedu/address/logic/commands/deleteroles/DeleteDeveloperRoleCommandTest.java
new file mode 100644
index 00000000000..da5a1161a41
--- /dev/null
+++ b/src/test/java/seedu/address/logic/commands/deleteroles/DeleteDeveloperRoleCommandTest.java
@@ -0,0 +1,116 @@
+package seedu.address.logic.commands.deleteroles;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
+import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.address.testutil.TypicalDevelopers.getTypicalAddressBook;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.logic.Messages;
+import seedu.address.logic.commands.addroles.AddDeveloperRoleCommand;
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.ModelManager;
+import seedu.address.model.UserPrefs;
+import seedu.address.model.developer.DeveloperRoles;
+import seedu.address.testutil.Assert;
+import seedu.address.testutil.DeveloperBuilder;
+
+public class DeleteDeveloperRoleCommandTest {
+
+ private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+
+ @Test
+ public void constructor_nullRole_throwsNullPointerException() {
+ Assert.assertThrows(NullPointerException.class, () -> new DeleteDeveloperRoleCommand(null));
+ }
+
+ @Test
+ public void execute_roleAcceptedByModel_deleteSuccessful() throws CommandException {
+
+ String validRole = "NewRole";
+ AddDeveloperRoleCommand addDeveloperRoleCommand = new AddDeveloperRoleCommand(validRole);
+ addDeveloperRoleCommand.execute(model);
+
+ DeleteDeveloperRoleCommand deleteDeveloperRoleCommand = new DeleteDeveloperRoleCommand(validRole);
+
+ String expectedMessage = String.format(DeleteDeveloperRoleCommand.MESSAGE_SUCCESS, validRole);
+
+ assertCommandSuccess(deleteDeveloperRoleCommand, model, expectedMessage, model);
+ }
+
+ @Test
+ public void execute_roleSomeoneUsing_throwsCommandException() throws CommandException {
+ // Assign a developer with the specified role
+ String roleWithDevelopers = "NewRole";
+ AddDeveloperRoleCommand addDeveloperRoleCommand = new AddDeveloperRoleCommand(roleWithDevelopers);
+ addDeveloperRoleCommand.execute(model);
+ DeveloperBuilder developerBuilder = new DeveloperBuilder().withRole(roleWithDevelopers);
+ model.addDeveloper(developerBuilder.build());
+
+ // Attempt to delete the role
+ DeleteDeveloperRoleCommand deleteDeveloperRoleCommand = new DeleteDeveloperRoleCommand(roleWithDevelopers);
+ String expectedResult = String.format(DeleteDeveloperRoleCommand.MESSAGE_CANNOT_DELETE_REPEAT,
+ Messages.format(roleWithDevelopers));
+
+ // Assert that the command throws an exception
+ assertCommandFailure(deleteDeveloperRoleCommand, model, expectedResult);
+
+ model.deleteDeveloper(developerBuilder.build());
+ deleteDeveloperRoleCommand.execute(model);
+ }
+
+
+ @Test
+ public void execute_roleNotInList_throwsCommandException() {
+ String nonExistingRole = "NonExistingRole";
+ DeleteDeveloperRoleCommand deleteDeveloperRoleCommand = new DeleteDeveloperRoleCommand(nonExistingRole);
+
+ assertCommandFailure(deleteDeveloperRoleCommand, model,
+ DeleteDeveloperRoleCommand.MESSAGE_CANNOT_DELETE_NONEXISTING
+ + DeleteDeveloperRoleCommand.MESSAGE_EXISTING_DEVELOPERS_ROLES
+ + DeveloperRoles.printRoles());
+ }
+
+ @Test
+ public void execute_roleIsPredefined_throwsCommandException() {
+ String roleWithDevelopers = "Developer";
+ DeleteDeveloperRoleCommand deleteDeveloperRoleCommand = new DeleteDeveloperRoleCommand(roleWithDevelopers);
+ assertThrows(CommandException.class, () -> deleteDeveloperRoleCommand.execute(model));
+ }
+
+ @Test
+ public void equals() {
+ String firstRole = "Tester";
+ String secondRole = "Developer";
+ DeleteDeveloperRoleCommand deleteFirstCommand = new DeleteDeveloperRoleCommand(firstRole);
+ DeleteDeveloperRoleCommand deleteSecondCommand = new DeleteDeveloperRoleCommand(secondRole);
+
+ // same object -> returns true
+ assertTrue(deleteFirstCommand.equals(deleteFirstCommand));
+
+ // role will no longer exists-> returns false
+ DeleteDeveloperRoleCommand deleteFirstCommandCopy = new DeleteDeveloperRoleCommand(firstRole);
+ assertFalse(deleteFirstCommand.equals(deleteFirstCommandCopy));
+
+ // different types -> returns false
+ assertFalse(deleteFirstCommand.equals(1));
+
+ // null -> returns false
+ assertFalse(deleteFirstCommand.equals(null));
+
+ // different developer role -> returns false
+ assertFalse(deleteFirstCommand.equals(deleteSecondCommand));
+ }
+
+ @Test
+ public void toStringTest() {
+ String roleName = "Tester";
+ DeleteDeveloperRoleCommand deleteDeveloperRoleCommand = new DeleteDeveloperRoleCommand(roleName);
+ assertEquals(deleteDeveloperRoleCommand.toString(), new DeleteDeveloperRoleCommand(roleName).toString());
+ }
+}
diff --git a/src/test/java/seedu/address/logic/commands/list/ListProjectCommandTest.java b/src/test/java/seedu/address/logic/commands/list/ListProjectCommandTest.java
index 36cd31b1c13..d7bfa327096 100644
--- a/src/test/java/seedu/address/logic/commands/list/ListProjectCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/list/ListProjectCommandTest.java
@@ -1,4 +1,43 @@
package seedu.address.logic.commands.list;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.address.testutil.TypicalProjects.getTypicalAddressBook;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.logic.commands.CommandResult;
+import seedu.address.model.Model;
+import seedu.address.model.ModelManager;
+import seedu.address.model.UserPrefs;
+
public class ListProjectCommandTest {
+
+ private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+
+ @Test
+ public void execute_listIsNotFiltered_showsSameList() {
+ ListProjectCommand listProjectCommand = new ListProjectCommand();
+ CommandResult commandResult = listProjectCommand.execute(model);
+
+ assertEquals(ListProjectCommand.MESSAGE_SUCCESS, commandResult.getFeedbackToUser());
+ assertEquals(model.getAddressBook().getProjectList(), model.getFilteredProjectList());
+ }
+
+ @Test
+ public void execute_listIsFiltered_showsEverything() {
+ // Assume the list is filtered by some predicate
+ model.updateFilteredProjectList(project -> project.getProjectDeadlines().equals("2023-01-01"));
+ ListProjectCommand listProjectCommand = new ListProjectCommand();
+ CommandResult commandResult = listProjectCommand.execute(model);
+
+ assertEquals(ListProjectCommand.MESSAGE_SUCCESS, commandResult.getFeedbackToUser());
+ assertEquals(model.getAddressBook().getProjectList(), model.getFilteredProjectList());
+ }
+
+ @Test
+ public void execute_modelIsNull_throwsAssertionError() {
+ ListProjectCommand listProjectCommand = new ListProjectCommand();
+ assertThrows(AssertionError.class, () -> listProjectCommand.execute(null));
+ }
}
diff --git a/src/test/java/seedu/address/model/VersionedAddressBookTest.java b/src/test/java/seedu/address/model/VersionedAddressBookTest.java
new file mode 100644
index 00000000000..0be58d4a166
--- /dev/null
+++ b/src/test/java/seedu/address/model/VersionedAddressBookTest.java
@@ -0,0 +1,85 @@
+package seedu.address.model;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.testutil.TypicalClients.getTypicalAddressBook;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.logic.commands.TabIndex;
+import seedu.address.logic.commands.exceptions.CommandException;
+
+
+public class VersionedAddressBookTest {
+
+ private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private VersionedAddressBook versionedAddressBook = new VersionedAddressBook(model.getAddressBook());
+
+ @Test
+ public void commit_validModelState_successfullyCommits() {
+ versionedAddressBook.commit(model, "Committing state", TabIndex.Client);
+
+ // Ensure that the model's address book is updated
+ assertEquals(model.getAddressBook(), versionedAddressBook.getCurrentState(1));
+
+ // Ensure that the state pointer has moved to the latest state
+ assertEquals(1, versionedAddressBook.getCurrentStatePointer());
+ }
+
+ @Test
+ public void undo_validModelState_successfullyUndoes() throws CommandException {
+ versionedAddressBook.commit(model, "Committing state", TabIndex.Client);
+ versionedAddressBook.undo(model);
+
+ // Ensure that the model's address book is updated to the previous state
+ assertEquals(model.getAddressBook(), versionedAddressBook.getCurrentState(1));
+
+ // Ensure that the state pointer has moved to the previous state
+ assertEquals(0, versionedAddressBook.getCurrentStatePointer());
+
+ // Ensure that the success message and tab index are retrieved
+ assertEquals("Committing state", versionedAddressBook.getPreviousMessage());
+ assertEquals(TabIndex.Client, versionedAddressBook.getPreviousTabIndex());
+ }
+
+ @Test
+ public void redo_validModelState_successfullyRedoes() throws CommandException {
+ versionedAddressBook.commit(model, "Committing state", TabIndex.Client);
+ versionedAddressBook.undo(model);
+ versionedAddressBook.redo(model);
+
+ // Ensure that the model's address book is updated to the next state
+ assertEquals(model.getAddressBook(), versionedAddressBook.getCurrentState(1));
+
+ // Ensure that the state pointer has moved to the next state
+ assertEquals(1, versionedAddressBook.getCurrentStatePointer());
+
+ // Ensure that the success message and tab index are retrieved
+ assertEquals("Committing state", versionedAddressBook.getPreviousMessageForRedo());
+ assertEquals(TabIndex.Client, versionedAddressBook.getPreviousTabIndexForRedo());
+ }
+
+ @Test
+ public void canUndo_noStatesToUndo_returnsFalse() {
+ assertFalse(versionedAddressBook.canUndo());
+ }
+
+ @Test
+ public void canRedo_noStatesToRedo_returnsFalse() {
+ assertFalse(versionedAddressBook.canRedo());
+ }
+
+ @Test
+ public void canUndo_hasStatesToUndo_returnsTrue() throws CommandException {
+ versionedAddressBook.commit(model, "Committing state", TabIndex.Client);
+ assertTrue(versionedAddressBook.canUndo());
+ }
+
+ @Test
+ public void canRedo_hasStatesToRedo_returnsTrue() throws CommandException {
+ versionedAddressBook.commit(model, "Committing state", TabIndex.Client);
+ versionedAddressBook.undo(model);
+ assertTrue(versionedAddressBook.canRedo());
+ }
+}