diff --git a/build.gradle b/build.gradle
index 8dba104ccbd..05ad2306835 100644
--- a/build.gradle
+++ b/build.gradle
@@ -20,6 +20,10 @@ checkstyle {
toolVersion = '10.2'
}
+run {
+ enableAssertions = true
+}
+
test {
useJUnitPlatform()
finalizedBy jacocoTestReport
diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md
index 8cc787ab80d..0b2cfe48812 100644
--- a/docs/DeveloperGuide.md
+++ b/docs/DeveloperGuide.md
@@ -257,6 +257,57 @@ _{more aspects and alternatives to be added}_
_{Explain here how the data archiving feature will be implemented}_
+### \[Implemented\] Searching for students
+
+The implemented search mechanism is facilitated by `SearchStudentCommand` and `SearchStudentCommandParser`.
+`SearchStudentCommandParser` implements the `Parser` interface and it's operations. `SearchStudentCommand` extends the
+`Command` class with the ability to update `Model`'s filtered person list using `Predicate`. It supports the following
+`Predicate`:
+
+- `NameContainsKeywordPredicate` — Search students based on name.
+- `EmailContainsKeywordPredicate` — Search students based on email.
+- `StudentIdContainsKeywordPredicate` — Search students based on student id.
+
+Given below is an example usage scenario and how the search mechanism behaves at each step.
+
+Example: `/search_student name/Bob`
+
+
+
+Step 1. The user executes `/search_student name/Bob` command to find students with the keyword `Bob` in their name.
+The `execute` command calls `AddressBookParser#parseCommand()`, which extracts the command word of the command and the
+arguments of the command.
+
+Step 2. The `AddressBookParser` then creates a new `SearchStudentCommandParser` and calling
+`SearchStudentCommandParser#parse()`, with `name/Bob` as the argument.
+
+Step 3. The `SearchStudentCommandParser` parses the arguments to determine which prefix the user is searching in.
+
+
+
+**Note:** Only one prefix can be used per command. If there are multiple prefixes, the method will throw an exception.
+
+
+
+Step 4. `SearchStudentCommandParser` creates `NameContainsKeywordPredicate` and `SearchStudentCommand`, passing the predicate
+as an argument into the command.
+
+Step 5. `LogicManager` calls `SearchStudentCommand#execute()`, passing `Model` as an argument. This method calls
+`Model#updateFilteredPersonList()` with the given predicate, updating the filtered list in `Model` with students whose
+name contains `Bob`.
+
+Step 6. Finally, a `CommandResult` is created and the new filtered is displayed to the user.
+
+### Design considerations:
+
+- **Alternative 1 (current choice):** Only one prefix allowed per command.
+ - Pros: Easy to implement.
+ - Cons: Does not allow users to fine tune searches based on multiple fields.
+
+- **Alternative 2:** Allow for multiple prefixes.
+ - Pros: Users can filter searches to a higher degree
+ - Cons: Handling combinations of different fields could be complex
+
---
## **Documentation, logging, testing, configuration, dev-ops**
diff --git a/docs/UserGuide.md b/docs/UserGuide.md
index 1cd1b037e6f..afdf7004b9d 100644
--- a/docs/UserGuide.md
+++ b/docs/UserGuide.md
@@ -13,6 +13,14 @@ TAHelper is a **desktop app for managing contacts, optimized for use via a Line
---
+## Target Audience
+
+TAHelper is specifically designed to assist and help Teaching Assistants (TA) of NUS Computer Science Modules,
+which caters to their need to store information in a way that is easy to track and visualise, as well as keep student's
+details in a centralised storage. Our target audience is specifically only TAs of NUS Computer Science Modules.
+
+## Purpose of User Guide
+
## Quick start
1. Ensure you have Java `11` or above installed in your Computer.
diff --git a/docs/diagrams/SearchStudentSequence.puml b/docs/diagrams/SearchStudentSequence.puml
new file mode 100644
index 00000000000..d4bc3d5db78
--- /dev/null
+++ b/docs/diagrams/SearchStudentSequence.puml
@@ -0,0 +1,79 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+
+box Logic LOGIC_COLOR_T1
+participant ":LogicManager" as LogicManager LOGIC_COLOR
+participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
+participant ":SearchStudentCommandParser" as SearchStudentCommandParser LOGIC_COLOR
+participant "p:NameContainsKeywordPredicate" as NameContainsKeywordPredicate LOGIC_COLOR
+participant "s:SearchStudentCommand" as SearchStudentCommand LOGIC_COLOR
+participant "r:CommandResult" as CommandResult LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant "m:Model" as Model MODEL_COLOR
+end box
+
+[-> LogicManager : execute("/search_student name/Bob")
+activate LogicManager
+
+LogicManager -> AddressBookParser : parseCommand("/search_student name/Bob")
+activate AddressBookParser
+
+create SearchStudentCommandParser
+AddressBookParser -> SearchStudentCommandParser
+activate SearchStudentCommandParser
+
+SearchStudentCommandParser --> AddressBookParser
+deactivate SearchStudentCommandParser
+
+AddressBookParser -> SearchStudentCommandParser : parse("name/Bob")
+activate SearchStudentCommandParser
+
+create NameContainsKeywordPredicate
+SearchStudentCommandParser -> NameContainsKeywordPredicate
+activate NameContainsKeywordPredicate
+
+NameContainsKeywordPredicate --> SearchStudentCommandParser
+deactivate NameContainsKeywordPredicate
+
+create SearchStudentCommand
+SearchStudentCommandParser -> SearchStudentCommand
+activate SearchStudentCommand
+
+SearchStudentCommand --> SearchStudentCommandParser :
+deactivate SearchStudentCommand
+
+SearchStudentCommandParser --> AddressBookParser : s
+deactivate SearchStudentCommandParser
+'Hidden arrow to position the destroy marker below the end of the activation bar.
+SearchStudentCommandParser -[hidden]-> AddressBookParser
+destroy SearchStudentCommandParser
+
+AddressBookParser --> LogicManager : s
+deactivate AddressBookParser
+
+LogicManager -> SearchStudentCommand : execute(m)
+activate SearchStudentCommand
+
+SearchStudentCommand -> Model : updateFilteredPersonList(p)
+activate Model
+
+Model --> SearchStudentCommand
+deactivate Model
+
+create CommandResult
+SearchStudentCommand -> CommandResult
+activate CommandResult
+
+CommandResult --> SearchStudentCommand
+deactivate CommandResult
+
+SearchStudentCommand --> LogicManager : r
+deactivate SearchStudentCommand
+
+[<--LogicManager
+deactivate LogicManager
+
+@enduml
diff --git a/src/main/java/seedu/address/logic/commands/AddTeamCommand.java b/src/main/java/seedu/address/logic/commands/AddTeamCommand.java
index 95eb4361acb..77f3c6b88b9 100644
--- a/src/main/java/seedu/address/logic/commands/AddTeamCommand.java
+++ b/src/main/java/seedu/address/logic/commands/AddTeamCommand.java
@@ -78,7 +78,7 @@ public CommandResult execute(Model model) throws CommandException {
if (tutorialClass.hasTeam(newTeam)) {
throw new CommandException(String.format(MESSAGE_DUPLICATE_TEAM, teamName, module, tutorialClass));
} else {
- tutorialClass.addTeam(newTeam);
+ model.addTeam(tutorialClass, newTeam);
}
if (teamSize != Integer.MAX_VALUE) {
diff --git a/src/main/java/seedu/address/logic/commands/allocatestudenttoteamcommands/AllocateStudentToTeamByEmailCommand.java b/src/main/java/seedu/address/logic/commands/allocatestudenttoteamcommands/AllocateStudentToTeamByEmailCommand.java
new file mode 100644
index 00000000000..5a4e998b063
--- /dev/null
+++ b/src/main/java/seedu/address/logic/commands/allocatestudenttoteamcommands/AllocateStudentToTeamByEmailCommand.java
@@ -0,0 +1,110 @@
+package seedu.address.logic.commands.allocatestudenttoteamcommands;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULECODE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_TEAMNAME;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_TUTORIALCLASS;
+
+import seedu.address.commons.util.ToStringBuilder;
+import seedu.address.logic.commands.CommandResult;
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.module.ModuleCode;
+import seedu.address.model.module.TutorialClass;
+import seedu.address.model.module.TutorialTeam;
+import seedu.address.model.person.Email;
+import seedu.address.model.person.Person;
+
+/**
+ * Allocates a student to a team in a tutorial Class in TAHelper.
+ */
+public class AllocateStudentToTeamByEmailCommand extends AllocateStudentToTeamCommand {
+
+ public static final String COMMAND_WORD = "/allocate_team";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Allocates a student a team in the tutorial class.\n"
+ + "Parameters: "
+ + PREFIX_EMAIL + "EMAIL "
+ + PREFIX_MODULECODE + "MODULE CODE "
+ + PREFIX_TUTORIALCLASS + "TUTORIAL CLASS "
+ + PREFIX_TEAMNAME + "TEAM NAME"
+ + "Example: " + COMMAND_WORD + " "
+ + PREFIX_EMAIL + "zack@bmail.com "
+ + PREFIX_MODULECODE + "CS2101 "
+ + PREFIX_TUTORIALCLASS + "T01 "
+ + PREFIX_TEAMNAME + "Team 1 ";
+
+ private final Email email;
+ private final ModuleCode moduleCode;
+ private final TutorialClass tutorialClass;
+ private final TutorialTeam tutorialTeam;
+
+ /**
+ * Creates an AllocateStudentToTeam object.
+ */
+ public AllocateStudentToTeamByEmailCommand(Email email, ModuleCode moduleCode,
+ TutorialClass tutorialClass, TutorialTeam tutorialTeam) {
+ this.email = email;
+ this.moduleCode = moduleCode;
+ this.tutorialClass = tutorialClass;
+ this.tutorialTeam = tutorialTeam;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+
+ if (model.findTutorialClassFromList(tutorialClass, moduleCode) == null) {
+ throw new CommandException(String.format(MESSAGE_CLASS_DOES_NOT_EXIST, tutorialClass, moduleCode));
+ }
+
+ ModuleCode module = model.findModuleFromList(moduleCode);
+ TutorialClass tutClass = model.findTutorialClassFromList(tutorialClass, module);
+
+ Person student = model.getUniquePersonList().getPersonByEmail(email);
+ TutorialTeam tutTeam = model.getTutorialTeam(tutClass, tutorialTeam);
+
+ if (student == null) {
+ throw new CommandException(MESSAGE_STUDENT_DOES_NOT_EXIST);
+ }
+
+ if (tutTeam == null) {
+ throw new CommandException(String.format(MESSAGE_TEAM_DOES_NOT_EXIST, tutorialTeam, tutClass));
+ }
+
+ // throws commandException if any condition fails
+ checkAllocateCondition(model, student, tutClass, tutTeam);
+ model.allocateStudentToTeam(student, tutTeam);
+
+ return new CommandResult(String.format(MESSAGE_SUCCESS, tutTeam));
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof AllocateStudentToTeamCommand)) {
+ return false;
+ }
+
+ AllocateStudentToTeamByEmailCommand otherAllocateCommand = (AllocateStudentToTeamByEmailCommand) other;
+ return this.email.equals(otherAllocateCommand.email)
+ && this.moduleCode.equals(otherAllocateCommand.moduleCode)
+ && this.tutorialClass.equals(otherAllocateCommand.tutorialClass)
+ && this.tutorialTeam.equals(otherAllocateCommand.tutorialTeam);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("email", email)
+ .add("moduleCode", moduleCode)
+ .add("tutorialClass", tutorialClass)
+ .add("tutorialTeam", tutorialTeam)
+ .toString();
+ }
+}
diff --git a/src/main/java/seedu/address/logic/commands/allocatestudenttoteamcommands/AllocateStudentToTeamByIndexCommand.java b/src/main/java/seedu/address/logic/commands/allocatestudenttoteamcommands/AllocateStudentToTeamByIndexCommand.java
new file mode 100644
index 00000000000..e55a0db0aaf
--- /dev/null
+++ b/src/main/java/seedu/address/logic/commands/allocatestudenttoteamcommands/AllocateStudentToTeamByIndexCommand.java
@@ -0,0 +1,117 @@
+package seedu.address.logic.commands.allocatestudenttoteamcommands;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_INDEX;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULECODE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_TEAMNAME;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_TUTORIALCLASS;
+
+import seedu.address.commons.core.index.Index;
+import seedu.address.commons.util.CollectionUtil;
+import seedu.address.commons.util.ToStringBuilder;
+import seedu.address.logic.commands.CommandResult;
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.module.ModuleCode;
+import seedu.address.model.module.TutorialClass;
+import seedu.address.model.module.TutorialTeam;
+import seedu.address.model.person.Person;
+
+/**
+ * Allocates a student to a team in a tutorial Class in TAHelper.
+ */
+public class AllocateStudentToTeamByIndexCommand extends AllocateStudentToTeamCommand {
+
+ public static final String COMMAND_WORD = "/allocate_team";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Allocates a student a team in the tutorial class.\n"
+ + "Parameters: "
+ + PREFIX_INDEX + "INDEX "
+ + PREFIX_MODULECODE + "MODULE CODE "
+ + PREFIX_TUTORIALCLASS + "TUTORIAL CLASS "
+ + PREFIX_TEAMNAME + "TEAM NAME"
+ + "Example: " + COMMAND_WORD + " "
+ + PREFIX_INDEX + "1 "
+ + PREFIX_MODULECODE + "CS2101 "
+ + PREFIX_TUTORIALCLASS + "T01 "
+ + PREFIX_TEAMNAME + "Team 1 ";
+
+ public static final String MESSAGE_PERSON_INDEX_NOT_FOUND =
+ "Student at index %d not found inside tutorial class %s";
+ private final Index index;
+ private final ModuleCode moduleCode;
+ private final TutorialClass tutorialClass;
+ private final TutorialTeam tutorialTeam;
+
+ /**
+ * Creates an AllocateStudentToTeam object.
+ */
+ public AllocateStudentToTeamByIndexCommand(Index index, ModuleCode moduleCode,
+ TutorialClass tutorialClass, TutorialTeam tutorialTeam) {
+ CollectionUtil.requireAllNonNull(index, moduleCode, tutorialClass, tutorialTeam);
+ this.index = index;
+ this.moduleCode = moduleCode;
+ this.tutorialClass = tutorialClass;
+ this.tutorialTeam = tutorialTeam;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+
+ if (model.findTutorialClassFromList(tutorialClass, moduleCode) == null) {
+ throw new CommandException(String.format(MESSAGE_CLASS_DOES_NOT_EXIST, tutorialClass, moduleCode));
+ }
+
+ ModuleCode module = model.findModuleFromList(moduleCode);
+ TutorialClass tutClass = model.findTutorialClassFromList(tutorialClass, module);
+
+ Person studentToAllocate;
+ try {
+ studentToAllocate = model.getStudentsInTutorialClass(tutClass).get(index.getZeroBased());
+ } catch (IndexOutOfBoundsException err) {
+ throw new CommandException(
+ String.format(MESSAGE_PERSON_INDEX_NOT_FOUND, index.getOneBased(), tutClass));
+ }
+
+ TutorialTeam tutTeam = model.getTutorialTeam(tutClass, tutorialTeam);
+
+ if (tutTeam == null) {
+ throw new CommandException(MESSAGE_STUDENT_DOES_NOT_EXIST);
+ }
+
+ // throws commandException if any condition fails
+ checkAllocateCondition(model, studentToAllocate, tutClass, tutTeam);
+ model.allocateStudentToTeam(studentToAllocate, tutTeam);
+
+ return new CommandResult(String.format(MESSAGE_SUCCESS, tutTeam));
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof AllocateStudentToTeamCommand)) {
+ return false;
+ }
+
+ AllocateStudentToTeamByIndexCommand otherAllocateCommand = (AllocateStudentToTeamByIndexCommand) other;
+ return this.index.equals(otherAllocateCommand.index)
+ && this.moduleCode.equals(otherAllocateCommand.moduleCode)
+ && this.tutorialClass.equals(otherAllocateCommand.tutorialClass)
+ && this.tutorialTeam.equals(otherAllocateCommand.tutorialTeam);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("index", index)
+ .add("moduleCode", moduleCode)
+ .add("tutorialClass", tutorialClass)
+ .add("tutorialTeam", tutorialTeam)
+ .toString();
+ }
+}
diff --git a/src/main/java/seedu/address/logic/commands/allocatestudenttoteamcommands/AllocateStudentToTeamByStuIdCommand.java b/src/main/java/seedu/address/logic/commands/allocatestudenttoteamcommands/AllocateStudentToTeamByStuIdCommand.java
new file mode 100644
index 00000000000..c7c8feb83d2
--- /dev/null
+++ b/src/main/java/seedu/address/logic/commands/allocatestudenttoteamcommands/AllocateStudentToTeamByStuIdCommand.java
@@ -0,0 +1,112 @@
+package seedu.address.logic.commands.allocatestudenttoteamcommands;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULECODE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_STUDENTID;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_TEAMNAME;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_TUTORIALCLASS;
+
+import seedu.address.commons.util.CollectionUtil;
+import seedu.address.commons.util.ToStringBuilder;
+import seedu.address.logic.commands.CommandResult;
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.module.ModuleCode;
+import seedu.address.model.module.TutorialClass;
+import seedu.address.model.module.TutorialTeam;
+import seedu.address.model.person.Person;
+import seedu.address.model.person.StudentId;
+
+/**
+ * Allocates a student to a team in a tutorial Class in TAHelper.
+ */
+public class AllocateStudentToTeamByStuIdCommand extends AllocateStudentToTeamCommand {
+
+ public static final String COMMAND_WORD = "/allocate_team";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Allocates a student a team in the tutorial class.\n"
+ + "Parameters: "
+ + PREFIX_STUDENTID + "STUDENT ID "
+ + PREFIX_MODULECODE + "MODULE CODE "
+ + PREFIX_TUTORIALCLASS + "TUTORIAL CLASS "
+ + PREFIX_TEAMNAME + "TEAM NAME"
+ + "Example: " + COMMAND_WORD + " "
+ + PREFIX_STUDENTID + "A1234567L "
+ + PREFIX_MODULECODE + "CS2101 "
+ + PREFIX_TUTORIALCLASS + "T01 "
+ + PREFIX_TEAMNAME + "Team 1 ";
+
+ private final StudentId studentId;
+ private final ModuleCode moduleCode;
+ private final TutorialClass tutorialClass;
+ private final TutorialTeam tutorialTeam;
+
+ /**
+ * Creates an AllocateStudentToTeam object.
+ */
+ public AllocateStudentToTeamByStuIdCommand(StudentId studentId, ModuleCode moduleCode,
+ TutorialClass tutorialClass, TutorialTeam tutorialTeam) {
+ CollectionUtil.requireAllNonNull(studentId, moduleCode, tutorialClass, tutorialTeam);
+ this.studentId = studentId;
+ this.moduleCode = moduleCode;
+ this.tutorialClass = tutorialClass;
+ this.tutorialTeam = tutorialTeam;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+
+ if (model.findTutorialClassFromList(tutorialClass, moduleCode) == null) {
+ throw new CommandException(MESSAGE_CLASS_DOES_NOT_EXIST);
+ }
+
+ ModuleCode module = model.findModuleFromList(moduleCode);
+ TutorialClass tutClass = model.findTutorialClassFromList(tutorialClass, module);
+
+ Person student = model.getUniquePersonList().getPerson(studentId);
+ TutorialTeam tutTeam = model.getTutorialTeam(tutClass, tutorialTeam);
+
+ if (student == null) {
+ throw new CommandException(MESSAGE_STUDENT_DOES_NOT_EXIST);
+ }
+
+ if (tutTeam == null) {
+ throw new CommandException(String.format(MESSAGE_TEAM_DOES_NOT_EXIST, tutorialTeam, tutClass));
+ }
+
+ // throws commandException if any condition fails
+ checkAllocateCondition(model, student, tutClass, tutTeam);
+ model.allocateStudentToTeam(student, tutTeam);
+
+ return new CommandResult(String.format(MESSAGE_SUCCESS, tutTeam));
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof AllocateStudentToTeamCommand)) {
+ return false;
+ }
+
+ AllocateStudentToTeamByStuIdCommand otherAllocateCommand = (AllocateStudentToTeamByStuIdCommand) other;
+ return this.studentId.equals(otherAllocateCommand.studentId)
+ && this.moduleCode.equals(otherAllocateCommand.moduleCode)
+ && this.tutorialClass.equals(otherAllocateCommand.tutorialClass)
+ && this.tutorialTeam.equals(otherAllocateCommand.tutorialTeam);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("studentId", studentId)
+ .add("moduleCode", moduleCode)
+ .add("tutorialClass", tutorialClass)
+ .add("tutorialTeam", tutorialTeam)
+ .toString();
+ }
+}
diff --git a/src/main/java/seedu/address/logic/commands/allocatestudenttoteamcommands/AllocateStudentToTeamCommand.java b/src/main/java/seedu/address/logic/commands/allocatestudenttoteamcommands/AllocateStudentToTeamCommand.java
new file mode 100644
index 00000000000..8a92630a68d
--- /dev/null
+++ b/src/main/java/seedu/address/logic/commands/allocatestudenttoteamcommands/AllocateStudentToTeamCommand.java
@@ -0,0 +1,85 @@
+package seedu.address.logic.commands.allocatestudenttoteamcommands;
+
+import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULECODE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_STUDENTID;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_TEAMNAME;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_TUTORIALCLASS;
+
+import seedu.address.commons.util.ToStringBuilder;
+import seedu.address.logic.commands.Command;
+import seedu.address.logic.commands.CommandResult;
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.module.TutorialClass;
+import seedu.address.model.module.TutorialTeam;
+import seedu.address.model.person.Person;
+
+/**
+ * Allocates a student to a team in a tutorial Class in TAHelper.
+ */
+public abstract class AllocateStudentToTeamCommand extends Command {
+
+ public static final String COMMAND_WORD = "/allocate_team";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Allocates a student a team in the tutorial class.\n"
+ + "Parameters: "
+ + PREFIX_STUDENTID + "STUDENT ID "
+ + PREFIX_MODULECODE + "MODULE CODE "
+ + PREFIX_TUTORIALCLASS + "TUTORIAL CLASS "
+ + PREFIX_TEAMNAME + "TEAM NAME"
+ + "Example: " + COMMAND_WORD + " "
+ + PREFIX_STUDENTID + "A1234567L "
+ + PREFIX_MODULECODE + "CS2101 "
+ + PREFIX_TUTORIALCLASS + "T01 "
+ + PREFIX_TEAMNAME + "Team 1 ";
+
+ public static final String MESSAGE_SUCCESS = "Allocate student to team: %s";
+ public static final String MESSAGE_STUDENT_NOT_IN_TUTORIAL = "Student needs to be in that tutorial group first.";
+ public static final String MESSAGE_STUDENT_DOES_NOT_EXIST = "Student does not exist in system";
+ public static final String MESSAGE_TEAM_DOES_NOT_EXIST = "Team %s does not exist in tutorial class %s";
+ public static final String MESSAGE_CLASS_DOES_NOT_EXIST = "Tutorial class %s does not exist in module %s";
+
+ public static final String MESSAGE_DUPLICATE_PERSON_IN_TEAM = "This person already exists in a team"
+ + " in the tutorial class %s!";
+ public static final String MESSAGE_TEAM_SIZE_EXCEEDED = "Max team size of %d reached";
+
+ public AllocateStudentToTeamCommand() {}
+
+ @Override
+ public abstract CommandResult execute(Model model) throws CommandException;
+ @Override
+ public abstract boolean equals(Object other);
+
+ /**
+ * Check the condition needed to allocate the student to a tutorial team.
+ * @param model
+ * @param student
+ * @param tutClass
+ * @param tutorialTeam
+ * @throws CommandException
+ */
+ public void checkAllocateCondition(Model model, Person student, TutorialClass tutClass, TutorialTeam tutorialTeam)
+ throws CommandException {
+ if (!model.isStudentInTutorialClass(student, tutClass)) {
+ throw new CommandException(MESSAGE_STUDENT_NOT_IN_TUTORIAL);
+ }
+
+ if (!model.hasTeamInTutorial(tutClass, tutorialTeam)) {
+ throw new CommandException(String.format(MESSAGE_TEAM_DOES_NOT_EXIST, tutorialTeam, tutClass));
+ }
+
+ if (model.isStudentInAnyTeam(student, tutClass)) {
+ throw new CommandException(String.format(MESSAGE_DUPLICATE_PERSON_IN_TEAM, tutClass));
+ }
+
+ if (model.hasTeamSizeExceeded(tutorialTeam)) {
+ throw new CommandException(String.format(MESSAGE_TEAM_SIZE_EXCEEDED, tutorialTeam.getTeamSize()));
+ }
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .toString();
+ }
+}
diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java
index fef5d6b944d..a641b8ff0f4 100644
--- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java
+++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java
@@ -26,6 +26,7 @@
import seedu.address.logic.commands.SortStudentCommand;
import seedu.address.logic.commands.ViewTeamCommand;
import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassCommand;
+import seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamCommand;
import seedu.address.logic.commands.deletestudentcommands.DeleteStudentCommand;
import seedu.address.logic.commands.deletestudentfromclasscommands.DeleteStudentFromClassCommand;
import seedu.address.logic.parser.exceptions.ParseException;
@@ -122,6 +123,9 @@ public Command parseCommand(String userInput) throws ParseException {
case ViewTeamCommand.COMMAND_WORD:
return new ViewTeamCommandParser().parse(arguments);
+ case AllocateStudentToTeamCommand.COMMAND_WORD:
+ return new AllocateStudentToTeamCommandParser().parse(arguments);
+
default:
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
diff --git a/src/main/java/seedu/address/logic/parser/AllocateStudentToTeamCommandParser.java b/src/main/java/seedu/address/logic/parser/AllocateStudentToTeamCommandParser.java
new file mode 100644
index 00000000000..014ad99b96d
--- /dev/null
+++ b/src/main/java/seedu/address/logic/parser/AllocateStudentToTeamCommandParser.java
@@ -0,0 +1,78 @@
+package seedu.address.logic.parser;
+
+import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_INDEX;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULECODE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_STUDENTID;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_TEAMNAME;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_TUTORIALCLASS;
+
+import java.util.stream.Stream;
+
+import seedu.address.commons.core.index.Index;
+import seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamByEmailCommand;
+import seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamByIndexCommand;
+import seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamByStuIdCommand;
+import seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamCommand;
+import seedu.address.logic.parser.exceptions.ParseException;
+import seedu.address.model.module.ModuleCode;
+import seedu.address.model.module.TutorialClass;
+import seedu.address.model.module.TutorialTeam;
+import seedu.address.model.person.Email;
+import seedu.address.model.person.StudentId;
+
+/**
+ * Parses input arguments and creates a new AllocateStudentToTeamCommand object
+ */
+public class AllocateStudentToTeamCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the
+ * AllocateStudentToTeam and returns an AllocateStudentToTeamCommand object for
+ * execution.
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public AllocateStudentToTeamCommand parse(String args) throws ParseException {
+ ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_STUDENTID, PREFIX_EMAIL,
+ PREFIX_INDEX, PREFIX_MODULECODE, PREFIX_TUTORIALCLASS, PREFIX_TEAMNAME);
+
+ boolean doesStudentIdExist = argMultimap.getValue(PREFIX_STUDENTID).isPresent();
+ boolean doesEmailExist = argMultimap.getValue(PREFIX_EMAIL).isPresent();
+ boolean doesIndexExist = argMultimap.getValue(PREFIX_INDEX).isPresent();
+
+ if (!arePrefixesPresent(argMultimap, PREFIX_MODULECODE,
+ PREFIX_TUTORIALCLASS, PREFIX_TEAMNAME)
+ || !(doesStudentIdExist || doesEmailExist || doesIndexExist)
+ || !argMultimap.getPreamble().isEmpty()) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, AllocateStudentToTeamCommand.MESSAGE_USAGE));
+ }
+
+ argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_STUDENTID, PREFIX_EMAIL, PREFIX_INDEX,
+ PREFIX_MODULECODE, PREFIX_TUTORIALCLASS, PREFIX_TEAMNAME);
+
+ ModuleCode moduleCode = ParserUtil.parseModuleCode(argMultimap.getValue(PREFIX_MODULECODE).get());
+ TutorialClass tutorialClass = ParserUtil.parseTutorialClass(argMultimap.getValue(PREFIX_TUTORIALCLASS).get());
+ TutorialTeam tutorialTeam = ParserUtil.parseTutorialTeam(argMultimap.getValue(PREFIX_TEAMNAME).get());
+
+ if (doesStudentIdExist) {
+ StudentId studentId = ParserUtil.parseStudentId(argMultimap.getValue(PREFIX_STUDENTID).get());
+ return new AllocateStudentToTeamByStuIdCommand(studentId, moduleCode, tutorialClass, tutorialTeam);
+ } else if (doesEmailExist) {
+ Email email = ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get());
+ return new AllocateStudentToTeamByEmailCommand(email, moduleCode, tutorialClass, tutorialTeam);
+ } else {
+ Index index = ParserUtil.parseIndex(argMultimap.getValue(PREFIX_INDEX).get());
+ return new AllocateStudentToTeamByIndexCommand(index, moduleCode, tutorialClass, tutorialTeam);
+ }
+ }
+
+ /**
+ * Returns true if none of the prefixes contains empty {@code Optional} values in the given
+ * {@code ArgumentMultimap}.
+ */
+ private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
+ return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
+ }
+}
diff --git a/src/main/java/seedu/address/logic/parser/CliSyntax.java b/src/main/java/seedu/address/logic/parser/CliSyntax.java
index 9bc62d29b00..385c321799f 100644
--- a/src/main/java/seedu/address/logic/parser/CliSyntax.java
+++ b/src/main/java/seedu/address/logic/parser/CliSyntax.java
@@ -13,6 +13,7 @@ public class CliSyntax {
public static final Prefix PREFIX_STUDENTID = new Prefix("id/");
public static final Prefix PREFIX_MODULECODE = new Prefix("module/");
public static final Prefix PREFIX_TUTORIALCLASS = new Prefix("tutorial/");
+ public static final Prefix PREFIX_TEAMNAME = new Prefix("team/");
public static final Prefix PREFIX_TAG = new Prefix("tag/");
public static final Prefix PREFIX_DESCRIPTION = new Prefix("description/");
public static final Prefix PREFIX_TEAM_SIZE = new Prefix("size/");
diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java
index 12010548824..5962c7c69c8 100644
--- a/src/main/java/seedu/address/logic/parser/ParserUtil.java
+++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java
@@ -11,6 +11,7 @@
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.module.ModuleCode;
import seedu.address.model.module.TutorialClass;
+import seedu.address.model.module.TutorialTeam;
import seedu.address.model.person.Email;
import seedu.address.model.person.Name;
import seedu.address.model.person.StudentId;
@@ -109,6 +110,20 @@ public static TutorialClass parseTutorialClass(String tutorial) throws ParseExce
return new TutorialClass(trimmedTutorial);
}
+ /**
+ * Parses a {@code String team} into an {@code TutorialTeam}.
+ * Leading and trailing whitespaces will be trimmed.
+ * @throws ParseException if the given {@code team} is invalid.
+ */
+ public static TutorialTeam parseTutorialTeam(String team) throws ParseException {
+ requireNonNull(team);
+ String trimmedTeam = team.trim();
+ if (!TutorialTeam.isValidTeamName(trimmedTeam)) {
+ throw new ParseException(TutorialTeam.MESSAGE_CONSTRAINTS);
+ }
+ return new TutorialTeam(trimmedTeam);
+ }
+
/**
* Parses a {@code String tag} into a {@code Tag}.
* Leading and trailing whitespaces will be trimmed.
diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java
index 6dd92aae306..8b8791b9c12 100644
--- a/src/main/java/seedu/address/model/AddressBook.java
+++ b/src/main/java/seedu/address/model/AddressBook.java
@@ -32,6 +32,9 @@ public class AddressBook implements ReadOnlyAddressBook {
private final ArrayList tutorialClasses;
private final ArrayList tutorialTeams;
+ private final UniquePersonList studentsInTeam;
+
+
/*
* The 'unusual' code block below is a non-static initialization block,
* sometimes used to avoid duplication
@@ -47,6 +50,8 @@ public class AddressBook implements ReadOnlyAddressBook {
modules = new ArrayList<>();
tutorialClasses = new ArrayList<>();
tutorialTeams = new ArrayList<>();
+ studentsInTeam = new UniquePersonList();
+
}
public AddressBook() {
@@ -85,12 +90,17 @@ public void setClass(List tutorialClasses) {
this.tutorialClasses.addAll(tutorialClasses);
}
- public void setTeams(List tutorialTeams) {
+ public void setTutorialTeams(List tutorialTeams) {
requireNonNull(tutorialTeams);
this.tutorialTeams.clear();
this.tutorialTeams.addAll(tutorialTeams);
}
+ public void setStudentsInTeam(List students) {
+ requireNonNull(students);
+ this.studentsInTeam.setPersons(students);
+ }
+
/**
* Resets the existing data of this {@code AddressBook} with {@code newData}.
*/
@@ -99,8 +109,8 @@ public void resetData(ReadOnlyAddressBook newData) {
setPersons(newData.getPersonList());
setModules(newData.getModuleList());
setClass(newData.getTutorialList());
- setTeams(newData.getTeamList());
-
+ setTutorialTeams(newData.getTutorialTeamList());
+ setStudentsInTeam(newData.getStudentsInTeamList());
}
//// person-level operations
@@ -238,6 +248,89 @@ public void deletePersonFromTutorialClass(Person person, ModuleCode module, Tuto
tutorialClassInList.deleteStudent(person);
}
+ /**
+ * Checks if a student is in the {@code tutorialClass} of that {@code moduleCode}
+ * @param student to check if student exist in tutorialClass.
+ * @param tutorialClass to check if the student is in
+ * @return a boolean indicating if the student is in that {@code tutorialClass}
+ */
+ public boolean isStudentInTutorialClass(Person student, TutorialClass tutorialClass) {
+ List students = tutorialClass.getStudents();
+ return students.stream().anyMatch(student::isSamePerson);
+ }
+
+ /**
+ * Allocates the {@code studentId} to the {@code tutorialTeam}
+ * @param tutorialTeam to allocate the student into.
+ */
+ public void allocateStudentToTeam(Person student, TutorialTeam tutorialTeam) {
+ requireNonNull(student);
+ requireNonNull(tutorialTeam);
+ tutorialTeam.addStudent(student);
+ }
+
+ /**
+ * Returns true if the {@code tutorialTeam} size has exceeded its limit.
+ * @param tutorialTeam size to check.
+ * @return a boolean that indicates whether the team size will be exceeded by adding another person.
+ */
+ public boolean hasTeamSizeExceeded(TutorialTeam tutorialTeam) {
+ requireNonNull(tutorialTeam);
+ int maxTeamSize = tutorialTeam.getTeamSize();
+ int currTeamSize = tutorialTeam.getStudents().size();
+ return (maxTeamSize <= currTeamSize);
+ };
+
+ /**
+ * Returns true if the {@code student} is already in a team of {@code tutorialClass}.
+ * @param tutorialClass of the teams.
+ * @param student to search for.
+ */
+ public boolean isStudentInAnyTeam(Person student, TutorialClass tutorialClass) {
+ boolean isStudentExist = false;
+ for (TutorialTeam tutorialTeam : tutorialClass.getTeams()) {
+ isStudentExist = tutorialTeam.hasStudentVerified(student, tutorialTeam);
+ if (isStudentExist) {
+ break;
+ }
+ }
+ return isStudentExist;
+ };
+
+ /**
+ * Returns true if a team with the same identity as {@code tutorialTeam} exists in the {@code tutorialClass}
+ * @param tutorialClass of the tutorialTeam.
+ * @param tutorialTeam to check if it exist.
+ */
+ public boolean hasTeamInTutorial(TutorialClass tutorialClass, TutorialTeam tutorialTeam) {
+ requireNonNull(tutorialClass);
+ requireNonNull(tutorialTeam);
+ ArrayList listOfTeams = tutorialClass.getTeams();
+ ObservableList teams = FXCollections.observableList(listOfTeams);
+ return teams.stream().anyMatch(tutorialClass::hasTeam);
+ }
+
+ public TutorialTeam getTutorialTeam(TutorialClass tutorialClass, TutorialTeam tutorialTeam) {
+ requireNonNull(tutorialClasses);
+ requireNonNull(tutorialTeam);
+ TutorialTeam tutTeam = tutorialClass.getTeams().stream()
+ .filter(team -> team.getTeamName().equals(tutorialTeam.getTeamName()))
+ .findFirst()
+ .orElse(null);
+ return tutTeam;
+ }
+
+ /**
+ * adds a team into the tutorial class
+ * @param tutorialClass to add the tutorialTeam to.
+ * @param tutorialTeam to be added into the tutorialClass.
+ */
+ public void addTeam(TutorialClass tutorialClass, TutorialTeam tutorialTeam) {
+ requireNonNull(tutorialClass);
+ requireNonNull(tutorialTeam);
+ tutorialClass.addTeam(tutorialTeam);
+ }
+
/**
* Replaces the given person {@code target} in the list with
* {@code editedPerson}.
@@ -275,11 +368,31 @@ public String toString() {
.toString();
}
+ @Override
+ public UniquePersonList getUniquePersonList() {
+ return this.persons;
+ }
+
@Override
public ObservableList getPersonList() {
return persons.asUnmodifiableObservableList();
}
+ @Override
+ public ObservableList getTutorialTeamList() {
+ return FXCollections.observableList(tutorialTeams);
+ }
+
+ @Override
+ public ObservableList getStudentsInTeamList() {
+ return studentsInTeam.asUnmodifiableObservableList();
+ }
+
+ @Override
+ public ObservableList getStudentsInTutorialClass(TutorialClass tutorialClass) {
+ return FXCollections.observableList(tutorialClass.getStudents());
+ }
+
@Override
public ObservableList getModuleList() {
return FXCollections.observableList(modules);
diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java
index 375cd3b101b..d29329bcf58 100644
--- a/src/main/java/seedu/address/model/Model.java
+++ b/src/main/java/seedu/address/model/Model.java
@@ -12,6 +12,7 @@
import seedu.address.model.person.Email;
import seedu.address.model.person.Person;
import seedu.address.model.person.StudentId;
+import seedu.address.model.person.UniquePersonList;
/**
* The API of the Model component.
@@ -96,12 +97,21 @@ public interface Model {
*/
void deletePerson(Person target);
+ /**
+ * adds a team into the tutorial class
+ * @param tutorialClass to add the tutorialTeam to.
+ * @param tutorialTeam to be added into the tutorialClass.
+ */
+ public void addTeam(TutorialClass tutorialClass, TutorialTeam tutorialTeam);
+
/**
* Deletes the given module.
* The module must exist in the address book.
*/
void deleteModule(ModuleCode target);
+ public TutorialTeam getTutorialTeam(TutorialClass tutorialClass, TutorialTeam tutorialTeam);
+
/**
* Adds the given person.
* {@code person} must not already exist in the address book.
@@ -114,6 +124,41 @@ public interface Model {
*/
void addModule(ModuleCode module);
+ /**
+ * Allocates the {@code student} to the {@code tutorialTeam}
+ * @param tutorialTeam to allocate the student into.
+ */
+ void allocateStudentToTeam(Person student, TutorialTeam tutorialTeam);
+
+ /**
+ * Returns true if a team with the same identity as {@code tutorialTeam} exists in the {@code tutorialClass}
+ * @param tutorialClass of the tutorialTeam.
+ * @param tutorialTeam to check if it exist.
+ */
+ boolean hasTeamInTutorial(TutorialClass tutorialClass, TutorialTeam tutorialTeam);
+
+ /**
+ * Returns true if the {@code student} is already in a team of {@code tutorialClass}.
+ * @param tutorialClass of the teams.
+ * @param student to search for.
+ */
+ public boolean isStudentInAnyTeam(Person student, TutorialClass tutorialClass);
+
+ /**
+ * Returns true if the {@code tutorialTeam} size has exceeded its limit.
+ * @param tutorialTeam size to check.
+ * @return a boolean that indicates whether the team size will be exceeded by adding another person.
+ */
+ boolean hasTeamSizeExceeded(TutorialTeam tutorialTeam);
+
+ /**
+ * Checks if a student is in the {@code tutorialClass} of that {@code moduleCode}
+ * @param student to check if student exist in tutorialClass.
+ * @param tutorialClass to check if the student is in
+ * @return a boolean indicating if the student is in that {@code tutorialClass}
+ */
+ boolean isStudentInTutorialClass(Person student, TutorialClass tutorialClass);
+
/**
* Adds the given person to the given tutorial class in the given module.
*/
@@ -128,8 +173,11 @@ public interface Model {
/** Returns an unmodifiable view of the filtered person list */
ObservableList getFilteredPersonList();
+ UniquePersonList getUniquePersonList();
ObservableList getFilteredModuleList();
ObservableList getSortedPersonList(Comparator comparator);
+ ObservableList getStudentsInTeamList();
+ ObservableList getStudentsInTutorialClass(TutorialClass tutorialClass);
/**
* Updates the filter of the filtered person list to filter by the given {@code predicate}.
diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java
index 8e45fb9cab6..3ffc77a56fc 100644
--- a/src/main/java/seedu/address/model/ModelManager.java
+++ b/src/main/java/seedu/address/model/ModelManager.java
@@ -19,6 +19,7 @@
import seedu.address.model.person.Email;
import seedu.address.model.person.Person;
import seedu.address.model.person.StudentId;
+import seedu.address.model.person.UniquePersonList;
/**
@@ -149,6 +150,52 @@ public void addPerson(Person person) {
updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
}
+ @Override
+ public void allocateStudentToTeam(Person student, TutorialTeam tutorialTeam) {
+ requireAllNonNull(student, tutorialTeam);
+ addressBook.allocateStudentToTeam(student, tutorialTeam);
+ }
+
+ @Override
+ public boolean hasTeamInTutorial(TutorialClass tutorialClass, TutorialTeam tutorialTeam) {
+ requireAllNonNull(tutorialClass, tutorialTeam);
+ return addressBook.hasTeamInTutorial(tutorialClass, tutorialTeam);
+ }
+
+ @Override
+ public TutorialTeam getTutorialTeam(TutorialClass tutorialClass, TutorialTeam tutorialTeam) {
+ requireAllNonNull(tutorialClass, tutorialTeam);
+ return addressBook.getTutorialTeam(tutorialClass, tutorialTeam);
+ }
+
+ /**
+ * Add a team to the tutorial class
+ * @param tutorialTeam to be added to the tutorial class
+ */
+ @Override
+ public void addTeam(TutorialClass tutorialClass, TutorialTeam tutorialTeam) {
+ requireNonNull(tutorialTeam);
+ addressBook.addTeam(tutorialClass, tutorialTeam);
+ }
+
+ @Override
+ public boolean hasTeamSizeExceeded(TutorialTeam tutorialTeam) {
+ requireNonNull(tutorialTeam);
+ return addressBook.hasTeamSizeExceeded(tutorialTeam);
+ };
+
+ @Override
+ public boolean isStudentInAnyTeam(Person student, TutorialClass tutorialClass) {
+ requireAllNonNull(student, tutorialClass);
+ return addressBook.isStudentInAnyTeam(student, tutorialClass);
+ }
+
+ @Override
+ public boolean isStudentInTutorialClass(Person student, TutorialClass tutorialClass) {
+ requireAllNonNull(student, tutorialClass);
+ return addressBook.isStudentInTutorialClass(student, tutorialClass);
+ }
+
@Override
public void addModule(ModuleCode module) {
addressBook.addModule(module,
@@ -182,6 +229,17 @@ public void setPerson(Person target, Person editedPerson) {
public ObservableList getFilteredPersonList() {
return filteredPersons;
}
+
+ /**
+ * Returns an unmodifiable view of the list of {@code Person} backed by the internal list of
+ * {@code versionedAddressBook}
+ * @Return UniquePersonList.
+ */
+ @Override
+ public UniquePersonList getUniquePersonList() {
+ return addressBook.getUniquePersonList();
+ }
+
/**
* Returns an unmodifiable view of the list of {@code Module} backed by the internal list of
* {@code versionedAddressBook}
@@ -197,6 +255,16 @@ public ObservableList getSortedPersonList(Comparator comparator)
return addressBook.getSortedPersonList();
}
+ @Override
+ public ObservableList getStudentsInTeamList() {
+ return addressBook.getStudentsInTeamList();
+ }
+
+ @Override
+ public ObservableList getStudentsInTutorialClass(TutorialClass tutorialClass) {
+ return addressBook.getStudentsInTutorialClass(tutorialClass);
+ }
+
@Override
public void updateFilteredPersonList(Predicate predicate) {
requireNonNull(predicate);
diff --git a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java
index 19b5459e1a7..e0e2d11556e 100644
--- a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java
+++ b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java
@@ -7,6 +7,7 @@
import seedu.address.model.module.TutorialClass;
import seedu.address.model.module.TutorialTeam;
import seedu.address.model.person.Person;
+import seedu.address.model.person.UniquePersonList;
/**
* Unmodifiable view of an address book
@@ -19,6 +20,8 @@ public interface ReadOnlyAddressBook {
*/
ObservableList getPersonList();
+ UniquePersonList getUniquePersonList();
+
/**
* Returns an unmodifiable view of the modules list.
* This list will not contain any duplicate modules.
@@ -27,6 +30,8 @@ public interface ReadOnlyAddressBook {
void setSortedPersonList(Comparator comparator);
ObservableList getSortedPersonList();
+ ObservableList getTutorialTeamList();
+ ObservableList getStudentsInTeamList();
/**
* Checks if the address book contains the specified module code.
@@ -38,5 +43,9 @@ public interface ReadOnlyAddressBook {
void addModule(ModuleCode moduleCode, String description);
ObservableList getTutorialList();
+
ObservableList getTeamList();
+
+ ObservableList getStudentsInTutorialClass(TutorialClass tutorialClass);
+
}
diff --git a/src/main/java/seedu/address/model/module/ModuleCode.java b/src/main/java/seedu/address/model/module/ModuleCode.java
index bae5af16c70..b570cf48ce0 100644
--- a/src/main/java/seedu/address/model/module/ModuleCode.java
+++ b/src/main/java/seedu/address/model/module/ModuleCode.java
@@ -22,7 +22,7 @@ public class ModuleCode {
public static final String VALIDATION_REGEX = "^[A-Z]{2,3}\\d{4}[A-Z]?$";
public final String moduleCode;
- private final ArrayList tutorialClasses;
+ private final List tutorialClasses;
private String description;
/**
@@ -75,7 +75,7 @@ public ModuleCode(String moduleCode, List tutorialClass, String d
* @param moduleCode of the module to be created
* @param tutorialClasses of the module to be created
*/
- public ModuleCode(String moduleCode, ArrayList tutorialClasses) {
+ public ModuleCode(String moduleCode, List tutorialClasses) {
requireAllNonNull(moduleCode);
checkArgument(isValidModuleCode(moduleCode), MESSAGE_CONSTRAINTS);
this.moduleCode = moduleCode;
@@ -94,7 +94,7 @@ public static boolean isValidModuleCode(String test) {
* @return the ArrayList of tutorial classes.
*/
public ArrayList getTutorialClasses() {
- return tutorialClasses;
+ return (ArrayList) tutorialClasses;
}
/**
diff --git a/src/main/java/seedu/address/model/module/TutorialClass.java b/src/main/java/seedu/address/model/module/TutorialClass.java
index de6eb6e4c3f..4d696826300 100644
--- a/src/main/java/seedu/address/model/module/TutorialClass.java
+++ b/src/main/java/seedu/address/model/module/TutorialClass.java
@@ -157,7 +157,12 @@ public void addTeam(TutorialTeam team) {
* @param team
*/
public boolean hasTeam(TutorialTeam team) {
- return teams.contains(team);
+ for (TutorialTeam tutorialTeam : this.teams) {
+ if (tutorialTeam.getTeamName().equals(team.getTeamName())) {
+ return true;
+ }
+ };
+ return false;
}
/**
diff --git a/src/main/java/seedu/address/model/module/TutorialTeam.java b/src/main/java/seedu/address/model/module/TutorialTeam.java
index 131a4364dc5..aeed896c855 100644
--- a/src/main/java/seedu/address/model/module/TutorialTeam.java
+++ b/src/main/java/seedu/address/model/module/TutorialTeam.java
@@ -177,6 +177,24 @@ public boolean hasStudent(Person student) {
return students.contains(student);
}
+ /**
+ * Checks if a student exist, check by their studentId.
+ * @return true if a person is in the list of students
+ */
+ public boolean hasStudentVerified(Person student, TutorialTeam tutorialTeam) {
+ ArrayList teamList = tutorialTeam.getStudents();
+ if (teamList.size() == 0 || teamList == null) {
+ return false;
+ }
+ for (Person eachStudent : teamList) {
+ if (eachStudent.getStudentId().value.equals(student.getStudentId().value)) {
+ return true;
+ }
+ }
+ return false;
+
+ }
+
@Override
public String toString() {
return teamName.toString();
diff --git a/src/main/java/seedu/address/model/person/Email.java b/src/main/java/seedu/address/model/person/Email.java
index be632593a54..8db1c6147c1 100644
--- a/src/main/java/seedu/address/model/person/Email.java
+++ b/src/main/java/seedu/address/model/person/Email.java
@@ -44,6 +44,16 @@ public Email(String email) {
value = email;
}
+ /**
+ * Returns true if 2 student emails are identical to {@code email} id value.
+ * @param email
+ * @return boolean if they are identical.
+ */
+ public boolean isSameEmail(Email email) {
+ requireNonNull(email);
+ return this.value.equals(email.value);
+ }
+
/**
* Returns if a given string is a valid email.
*/
diff --git a/src/main/java/seedu/address/model/person/StudentId.java b/src/main/java/seedu/address/model/person/StudentId.java
index b7a09a46b1b..3dbcb8a4b23 100644
--- a/src/main/java/seedu/address/model/person/StudentId.java
+++ b/src/main/java/seedu/address/model/person/StudentId.java
@@ -38,6 +38,16 @@ public static boolean isValidStudentId(String test) {
return test.matches(VALIDATION_REGEX);
}
+ /**
+ * Returns true if 2 student ids are identical to {@code studentId} id value.
+ * @param studentId
+ * @return boolean if they are identical.
+ */
+ public boolean isSameStudentId(StudentId studentId) {
+ requireNonNull(studentId);
+ return this.value.equals(studentId.value);
+ }
+
@Override
public String toString() {
return value;
diff --git a/src/main/java/seedu/address/model/person/UniquePersonList.java b/src/main/java/seedu/address/model/person/UniquePersonList.java
index 1287447aeff..8c474901587 100644
--- a/src/main/java/seedu/address/model/person/UniquePersonList.java
+++ b/src/main/java/seedu/address/model/person/UniquePersonList.java
@@ -36,6 +36,30 @@ public boolean contains(Person toCheck) {
return internalList.stream().anyMatch(toCheck::isSamePerson);
}
+ /**
+ * Return the Person object if the list contains the person with {@code studentId}
+ */
+ public Person getPerson(StudentId studentId) {
+ requireNonNull(studentId);
+ Person personMatch = internalList.stream()
+ .filter(person -> person.getStudentId().isSameStudentId(studentId))
+ .findFirst()
+ .orElse(null);
+ return personMatch;
+ }
+
+ /**
+ * Return the Person object if the list contains the person with {@code email}
+ */
+ public Person getPersonByEmail(Email email) {
+ requireNonNull(email);
+ Person personMatch = internalList.stream()
+ .filter(person -> person.getEmail().isSameEmail(email))
+ .findFirst()
+ .orElse(null);
+ return personMatch;
+ }
+
/**
* Adds a person to the list.
* The person must not already exist in the list.
diff --git a/src/main/java/seedu/address/storage/JsonAdaptedModule.java b/src/main/java/seedu/address/storage/JsonAdaptedModule.java
index d3206f85089..d882cbaa0e3 100644
--- a/src/main/java/seedu/address/storage/JsonAdaptedModule.java
+++ b/src/main/java/seedu/address/storage/JsonAdaptedModule.java
@@ -1,6 +1,7 @@
package seedu.address.storage;
import java.util.ArrayList;
+import java.util.List;
import java.util.stream.Collectors;
import com.fasterxml.jackson.annotation.JsonCreator;
@@ -9,6 +10,7 @@
import seedu.address.commons.exceptions.IllegalValueException;
import seedu.address.model.module.ModuleCode;
import seedu.address.model.module.TutorialClass;
+import seedu.address.model.person.StudentId;
/**
* Jackson-friendly version of {@link ModuleCode}.
@@ -18,7 +20,7 @@ class JsonAdaptedModule {
public static final String MISSING_FIELD_MESSAGE_FORMAT = "Module name is missing!";
private final String name;
- private final ArrayList tutorialClasses;
+ private final List tutorialClasses = new ArrayList<>();
private final String description;
/**
@@ -26,11 +28,13 @@ class JsonAdaptedModule {
*/
@JsonCreator
public JsonAdaptedModule(@JsonProperty("name") String name,
- @JsonProperty("tutorialClasses") ArrayList tutorialClasses,
+ @JsonProperty("tutorialClasses") List tutorialClasses,
@JsonProperty("description") String description) {
this.name = name;
- this.tutorialClasses = tutorialClasses;
this.description = description;
+ if (tutorialClasses != null) {
+ this.tutorialClasses.addAll(tutorialClasses);
+ }
}
/**
@@ -38,8 +42,8 @@ public JsonAdaptedModule(@JsonProperty("name") String name,
*/
public JsonAdaptedModule(ModuleCode source) {
name = source.toString();
- this.tutorialClasses = source.getTutorialClasses().stream().map(JsonAdaptedTutorialClass::new)
- .collect(Collectors.toCollection(ArrayList::new));
+ tutorialClasses.addAll(source.getTutorialClasses().stream().map(JsonAdaptedTutorialClass::new)
+ .collect(Collectors.toCollection(ArrayList::new)));
this.description = source.getDescription();
}
@@ -53,7 +57,7 @@ public String getModuleName() {
/**
* Retrieves tutorial classes from the module.
*/
- public ArrayList getTutorialClasses() {
+ public List getTutorialClasses() {
return tutorialClasses;
}
@@ -66,16 +70,21 @@ public ModuleCode toModelType() throws IllegalValueException {
if (!ModuleCode.isValidModuleCode(name)) {
throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, name));
}
- ArrayList tutorialClasses = new ArrayList<>();
+ final List listOfClass = new ArrayList<>();
for (JsonAdaptedTutorialClass tutorialClass : this.tutorialClasses) {
- tutorialClasses.add(tutorialClass.toModelType());
+ listOfClass.add(tutorialClass.toModelType());
}
+
ModuleCode moduleCode;
+ if (!ModuleCode.isValidModuleCode(name)) {
+ throw new IllegalValueException(StudentId.MESSAGE_CONSTRAINTS);
+ }
+
if (description != null && !description.isEmpty()) {
- moduleCode = new ModuleCode(name, tutorialClasses,
+ moduleCode = new ModuleCode(name, listOfClass,
description);
} else {
- moduleCode = new ModuleCode(name, tutorialClasses);
+ moduleCode = new ModuleCode(name, listOfClass);
}
return moduleCode;
diff --git a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java
index 06f62b98cb5..f979448b1c6 100644
--- a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java
+++ b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java
@@ -95,5 +95,4 @@ public Person toModelType() throws IllegalValueException {
final Set modelTags = new HashSet<>(personTags);
return new Person(modelName, modelEmail, modelStudentId, modelTags);
}
-
}
diff --git a/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java b/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java
index adaf8763c6e..8c4f40e0238 100644
--- a/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java
+++ b/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java
@@ -17,9 +17,10 @@
*/
public class JsonAdaptedTutorialClass {
+ public static final String MISSING_FIELD_MESSAGE_FORMAT = "tutorial name is missing!";
private final String tutorialName;
- private final List students;
- private final List teams;
+ private final List students = new ArrayList<>();
+ private final List teams = new ArrayList<>();
/**
* Constructs a {@code JsonAdaptedTutorialClass} with the given
@@ -30,17 +31,21 @@ public JsonAdaptedTutorialClass(@JsonProperty("tutorialName") String tutorialNam
@JsonProperty("teams") List teams,
@JsonProperty("students") List students) {
this.tutorialName = tutorialName;
- this.teams = teams != null ? new ArrayList<>(teams) : new ArrayList<>();
- this.students = students != null ? new ArrayList<>(students) : new ArrayList<>();
+ if (teams != null) {
+ this.teams.addAll(teams);
+ }
+ if (students != null) {
+ this.students.addAll(students);
+ }
}
/**
* Converts a given {@code TutorialClass} into this class for Jackson use.
*/
public JsonAdaptedTutorialClass(TutorialClass source) {
- this.tutorialName = source.tutorialName;
- this.teams = source.getTeams().stream().map(JsonAdaptedTutorialTeam::new).collect(Collectors.toList());
- this.students = source.getStudents().stream().map(JsonAdaptedPerson::new).collect(Collectors.toList());
+ this.tutorialName = source.getTutorialClass().tutorialName;
+ teams.addAll(source.getTeams().stream().map(JsonAdaptedTutorialTeam::new).collect(Collectors.toList()));
+ students.addAll(source.getStudents().stream().map(JsonAdaptedPerson::new).collect(Collectors.toList()));
}
public String getTutorialName() {
@@ -63,19 +68,23 @@ public List getStudents() {
* the adapted tutorial class.
*/
public TutorialClass toModelType() throws IllegalValueException {
- try {
- ArrayList students = new ArrayList<>();
- for (JsonAdaptedPerson student : this.students) {
- students.add(student.toModelType());
- }
- ArrayList teams = new ArrayList<>();
- for (JsonAdaptedTutorialTeam team : this.teams) {
- teams.add(team.toModelType());
- }
- return new TutorialClass(tutorialName, students, teams);
- } catch (IllegalValueException e) {
+ ArrayList listOfStudents = new ArrayList<>();
+ ArrayList listOfTeams = new ArrayList<>();
+
+ if (tutorialName == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, tutorialName));
+ }
+ if (!TutorialClass.isValidTutorialClass(tutorialName)) {
throw new IllegalValueException(TutorialClass.MESSAGE_CONSTRAINTS);
}
+
+ for (JsonAdaptedPerson student : students) {
+ listOfStudents.add(student.toModelType());
+ }
+ for (JsonAdaptedTutorialTeam team : teams) {
+ listOfTeams.add(team.toModelType());
+ }
+ return new TutorialClass(tutorialName, listOfStudents, listOfTeams);
}
@Override
diff --git a/src/main/java/seedu/address/storage/JsonAdaptedTutorialTeam.java b/src/main/java/seedu/address/storage/JsonAdaptedTutorialTeam.java
index cc53e57b3d7..30b7460e232 100644
--- a/src/main/java/seedu/address/storage/JsonAdaptedTutorialTeam.java
+++ b/src/main/java/seedu/address/storage/JsonAdaptedTutorialTeam.java
@@ -16,9 +16,10 @@
*/
public class JsonAdaptedTutorialTeam {
+ public static final String MISSING_FIELD_MESSAGE_FORMAT = "team name is missing!";
private final String teamName;
private final int teamSize;
- private final List students;
+ private final List students = new ArrayList<>();
/**
* Constructs a {@code JsonAdaptedTutorialTeam} with the given
@@ -29,7 +30,9 @@ public JsonAdaptedTutorialTeam(@JsonProperty("teamName") String teamName,
@JsonProperty("teamSize") int teamSize,
@JsonProperty("students") List students) {
this.teamName = teamName;
- this.students = students != null ? new ArrayList<>(students) : new ArrayList<>();
+ if (students != null) {
+ this.students.addAll(students);
+ }
this.teamSize = teamSize;
}
@@ -37,9 +40,9 @@ public JsonAdaptedTutorialTeam(@JsonProperty("teamName") String teamName,
* Converts a given {@code TutorialTeam} into this class for Jackson use.
*/
public JsonAdaptedTutorialTeam(TutorialTeam source) {
- this.teamName = source.teamName.fullName;
- this.teamSize = source.teamSize;
- this.students = source.getStudents().stream().map(JsonAdaptedPerson::new).collect(Collectors.toList());
+ this.teamName = source.getTeamName();
+ this.teamSize = source.getTeamSize();
+ students.addAll(source.getStudents().stream().map(JsonAdaptedPerson::new).collect(Collectors.toList()));
}
public String getTeamName() {
@@ -51,7 +54,7 @@ public int getTeamSize() {
}
public List getStudents() {
- return new ArrayList<>(students);
+ return this.students;
}
/**
@@ -62,15 +65,21 @@ public List getStudents() {
* the adapted tutorial team.
*/
public TutorialTeam toModelType() throws IllegalValueException {
- try {
- ArrayList students = new ArrayList<>();
- for (JsonAdaptedPerson student : this.students) {
- students.add(student.toModelType());
- }
- return new TutorialTeam(teamName, students, teamSize);
- } catch (IllegalValueException e) {
- throw new IllegalValueException(TutorialTeam.MESSAGE_CONSTRAINTS);
+ final ArrayList listOfStudents = new ArrayList<>();
+ if (teamName == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, teamName));
+ }
+ if (!TutorialTeam.isValidTeamName(teamName)) {
+ throw new IllegalValueException(TutorialTeam.MESSAGE_NAME_CONSTRAINTS);
+ }
+
+ if (!TutorialTeam.isValidSize(teamSize)) {
+ throw new IllegalValueException(TutorialTeam.MESSAGE_SIZE_CONSTRAINTS);
+ }
+ for (JsonAdaptedPerson student : students) {
+ listOfStudents.add(student.toModelType());
}
+ return new TutorialTeam(teamName, listOfStudents, teamSize);
}
@Override
diff --git a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java b/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java
index e67b72b8113..2f6b729990e 100644
--- a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java
+++ b/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java
@@ -33,7 +33,7 @@ class JsonSerializableAddressBook {
*/
@JsonCreator
public JsonSerializableAddressBook(@JsonProperty("persons") List persons,
- @JsonProperty("modules") List modules) {
+ @JsonProperty("modules") List modules) {
if (persons != null) {
this.persons.addAll(persons);
}
@@ -72,7 +72,7 @@ public AddressBook toModelType() throws IllegalValueException {
throw new IllegalValueException(MESSAGE_DUPLICATE_MODULE);
}
addressBook.addModule(module,
- module.getDescription());
+ module.getDescription());
}
return addressBook;
}
@@ -111,5 +111,4 @@ public void addPersonToTutorialClass(String moduleName, String tutorialName, Per
throw new IllegalValueException("Module containing tutorial class '" + tutorialName + "' not found.");
}
}
-
}
diff --git a/src/test/java/seedu/address/logic/commands/AddStudentCommandTest.java b/src/test/java/seedu/address/logic/commands/AddStudentCommandTest.java
index 00afd61f717..4d3e6e0170c 100644
--- a/src/test/java/seedu/address/logic/commands/AddStudentCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/AddStudentCommandTest.java
@@ -29,6 +29,7 @@
import seedu.address.model.person.Email;
import seedu.address.model.person.Person;
import seedu.address.model.person.StudentId;
+import seedu.address.model.person.UniquePersonList;
import seedu.address.testutil.PersonBuilder;
/**
@@ -139,6 +140,36 @@ public void setAddressBook(ReadOnlyAddressBook newData) {
throw new AssertionError("This method should not be called.");
}
+ @Override
+ public void allocateStudentToTeam(Person student, TutorialTeam tutorialTeam) {
+ throw new AssertionError("This method should not be called.");
+ };
+
+ @Override
+ public boolean hasTeamInTutorial(TutorialClass tutorialClass, TutorialTeam tutorialTeam) {
+ throw new AssertionError("This method should not be called.");
+ };
+
+ @Override
+ public TutorialTeam getTutorialTeam(TutorialClass tutorialClass, TutorialTeam tutorialTeam) {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public boolean isStudentInAnyTeam(Person student, TutorialClass tutorialClass) {
+ throw new AssertionError("This method should not be called.");
+ };
+
+ @Override
+ public boolean isStudentInTutorialClass(Person student, TutorialClass tutorialClass) {
+ throw new AssertionError("This method should not be called.");
+ };
+
+ @Override
+ public boolean hasTeamSizeExceeded(TutorialTeam tutorialTeam) {
+ throw new AssertionError("This method should not be called.");
+ }
+
@Override
public ReadOnlyAddressBook getAddressBook() {
throw new AssertionError("This method should not be called.");
@@ -169,6 +200,11 @@ public void addPersonToTutorialClass(Person person, ModuleCode moduleCode, Tutor
throw new AssertionError("This method should not be called.");
}
+ @Override
+ public void addTeam(TutorialClass tutorialClass, TutorialTeam tutorialTeam) {
+ throw new AssertionError("This method should not be called.");
+ };
+
@Override
public void deletePersonFromTutorialClass(Person person, ModuleCode moduleCode, TutorialClass tutorialClass) {
throw new AssertionError("This method should not be called.");
@@ -217,6 +253,21 @@ public ObservableList getSortedPersonList(Comparator comparator)
throw new AssertionError("This method should not be called.");
}
+ @Override
+ public UniquePersonList getUniquePersonList() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public ObservableList getStudentsInTeamList() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public ObservableList getStudentsInTutorialClass(TutorialClass tutorialClass) {
+ throw new AssertionError("This method should not be called.");
+ }
+
@Override
public void updateFilteredPersonList(Predicate predicate) {
throw new AssertionError("This method should not be called.");
diff --git a/src/test/java/seedu/address/logic/commands/AllocateStudentToTeamCommandTest.java b/src/test/java/seedu/address/logic/commands/AllocateStudentToTeamCommandTest.java
new file mode 100644
index 00000000000..4cc46ada069
--- /dev/null
+++ b/src/test/java/seedu/address/logic/commands/AllocateStudentToTeamCommandTest.java
@@ -0,0 +1,264 @@
+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.logic.commands.CommandTestUtil.VALID_EMAIL;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_MODULE_AMY;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_STUDENT_ID;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_STUDENT_ID_BOB;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TEAM_NAME;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TEAM_NAME_BOB;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TEAM_NAME_NEW;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TUTORIAL_AMY;
+import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
+import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamCommand.MESSAGE_DUPLICATE_PERSON_IN_TEAM;
+import static seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamCommand.MESSAGE_STUDENT_DOES_NOT_EXIST;
+import static seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamCommand.MESSAGE_TEAM_DOES_NOT_EXIST;
+import static seedu.address.testutil.TypicalPersons.ALICE;
+import static seedu.address.testutil.TypicalPersons.AMY;
+import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import seedu.address.commons.core.index.Index;
+import seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamByEmailCommand;
+import seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamByIndexCommand;
+import seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamByStuIdCommand;
+import seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamCommand;
+import seedu.address.model.Model;
+import seedu.address.model.ModelManager;
+import seedu.address.model.UserPrefs;
+import seedu.address.model.module.ModuleCode;
+import seedu.address.model.module.TutorialClass;
+import seedu.address.model.module.TutorialTeam;
+import seedu.address.model.person.Email;
+import seedu.address.model.person.Person;
+import seedu.address.model.person.StudentId;
+import seedu.address.testutil.PersonBuilder;
+
+
+public class AllocateStudentToTeamCommandTest {
+ private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private TutorialClass tutorialClass;
+ private Person validPerson;
+ private Person validOtherPerson;
+ private ModuleCode newModule;
+ private TutorialTeam newTeam;
+ private TutorialTeam tutTeam;
+
+ @BeforeEach
+ public void setUp() {
+ validPerson = new PersonBuilder(AMY).build();
+ validOtherPerson = new PersonBuilder(ALICE)
+ .withStudentId(VALID_STUDENT_ID_BOB).withEmail(VALID_EMAIL_BOB).build();
+ newModule = new ModuleCode(VALID_MODULE_AMY);
+ model.addModule(newModule);
+ model.addPerson(validPerson);
+ model.addPerson(validOtherPerson);
+ TutorialClass newTutorialClass = new TutorialClass(VALID_TUTORIAL_AMY);
+ newModule.addTutorialClass(newTutorialClass);
+ tutorialClass = newTutorialClass;
+ newTeam = new TutorialTeam(VALID_TEAM_NAME, 1);
+ tutTeam = new TutorialTeam(VALID_TEAM_NAME_BOB, 3);
+ tutorialClass.addTeam(tutTeam);
+ tutorialClass.addTeam(newTeam);
+ }
+
+ @Test
+ public void invalidAllocationToTeam_indexNotInSystem_failure() {
+ Index index = Index.fromOneBased(1000);
+ AllocateStudentToTeamByIndexCommand allocateStudentToTeamByIndexCommand = new
+ AllocateStudentToTeamByIndexCommand(index,
+ newModule, tutorialClass, newTeam);
+ assertCommandFailure(allocateStudentToTeamByIndexCommand, model,
+ String.format(AllocateStudentToTeamByIndexCommand.MESSAGE_PERSON_INDEX_NOT_FOUND,
+ index.getOneBased(), tutorialClass));
+ }
+
+ @Test
+ public void invalidAllocationToTeam_teamSizeExceeded_failure() {
+ tutorialClass.addStudent(validPerson);
+ newTeam.addStudent(validPerson);
+ tutorialClass.addStudent(validOtherPerson);
+ AllocateStudentToTeamByStuIdCommand allocateStudentToTeamByStuIdCommand = new
+ AllocateStudentToTeamByStuIdCommand(validOtherPerson.getStudentId(), newModule, tutorialClass, newTeam);
+ AllocateStudentToTeamByEmailCommand allocateStudentToTeamByEmailCommand = new
+ AllocateStudentToTeamByEmailCommand(validOtherPerson.getEmail(), newModule, tutorialClass, newTeam);
+ assertCommandFailure(allocateStudentToTeamByStuIdCommand, model,
+ String.format(AllocateStudentToTeamCommand.MESSAGE_TEAM_SIZE_EXCEEDED, newTeam.getTeamSize()));
+ assertCommandFailure(allocateStudentToTeamByEmailCommand, model,
+ String.format(AllocateStudentToTeamCommand.MESSAGE_TEAM_SIZE_EXCEEDED, newTeam.getTeamSize()));
+ }
+
+ @Test
+ public void invalidAllocationToTeam_studentNull_failure() {
+ AllocateStudentToTeamByStuIdCommand allocateStudentToTeamByStuIdCommand = new
+ AllocateStudentToTeamByStuIdCommand(new StudentId(VALID_STUDENT_ID), newModule, tutorialClass, newTeam);
+ AllocateStudentToTeamByEmailCommand allocateStudentToTeamByEmailCommand = new
+ AllocateStudentToTeamByEmailCommand(new Email(VALID_EMAIL), newModule, tutorialClass, newTeam);
+ assertCommandFailure(allocateStudentToTeamByStuIdCommand, model,
+ String.format(MESSAGE_STUDENT_DOES_NOT_EXIST));
+ assertCommandFailure(allocateStudentToTeamByEmailCommand, model,
+ String.format(MESSAGE_STUDENT_DOES_NOT_EXIST));
+ }
+
+ @Test
+ public void invalidAllocationToTeam_tutorialTeamNotExist_failure() {
+ TutorialTeam team = new TutorialTeam(VALID_TEAM_NAME_NEW);
+
+ AllocateStudentToTeamByStuIdCommand allocateStudentToTeamByStuIdCommand = new
+ AllocateStudentToTeamByStuIdCommand(validPerson.getStudentId(), newModule, tutorialClass,
+ team);
+ AllocateStudentToTeamByEmailCommand allocateStudentToTeamByEmailCommand = new
+ AllocateStudentToTeamByEmailCommand(validPerson.getEmail(), newModule, tutorialClass,
+ team);
+ assertCommandFailure(allocateStudentToTeamByStuIdCommand, model,
+ String.format(MESSAGE_TEAM_DOES_NOT_EXIST, team, tutorialClass));
+ assertCommandFailure(allocateStudentToTeamByEmailCommand, model,
+ String.format(MESSAGE_TEAM_DOES_NOT_EXIST, team, tutorialClass));
+ }
+
+ @Test
+ public void invalidAllocationToTeam_studentAlreadyInTeam_failure() {
+ tutorialClass.addStudent(validPerson);
+ newTeam.addStudent(validPerson);
+ AllocateStudentToTeamByStuIdCommand allocateStudentToTeamByStuIdCommand = new
+ AllocateStudentToTeamByStuIdCommand(validPerson.getStudentId(), newModule, tutorialClass,
+ tutTeam);
+ AllocateStudentToTeamByEmailCommand allocateStudentToTeamByEmailCommand = new
+ AllocateStudentToTeamByEmailCommand(validPerson.getEmail(), newModule, tutorialClass,
+ tutTeam);
+ assertCommandFailure(allocateStudentToTeamByStuIdCommand, model,
+ String.format(MESSAGE_DUPLICATE_PERSON_IN_TEAM, tutorialClass));
+ assertCommandFailure(allocateStudentToTeamByEmailCommand, model,
+ String.format(MESSAGE_DUPLICATE_PERSON_IN_TEAM, tutorialClass));
+ }
+
+
+
+ @Test
+ public void validAllocationToTeam_byEmailOrStudentId_success() {
+ tutorialClass.addStudent(validPerson);
+ tutorialClass.addStudent(validOtherPerson);
+ AllocateStudentToTeamByStuIdCommand allocateStudentToTeamByStuIdCommand = new
+ AllocateStudentToTeamByStuIdCommand(validPerson.getStudentId(),
+ newModule, tutorialClass, tutTeam);
+ AllocateStudentToTeamByEmailCommand allocateStudentToTeamByEmailCommand = new
+ AllocateStudentToTeamByEmailCommand(validOtherPerson.getEmail(),
+ newModule, tutorialClass, tutTeam);
+ assertCommandSuccess(allocateStudentToTeamByStuIdCommand, model,
+ String.format(AllocateStudentToTeamByIndexCommand.MESSAGE_SUCCESS, tutTeam), model);
+ assertCommandSuccess(allocateStudentToTeamByEmailCommand, model,
+ String.format(AllocateStudentToTeamByEmailCommand.MESSAGE_SUCCESS, tutTeam), model);
+ }
+
+
+ @Test
+ public void validAllocationToTeam_indexInSystem_success() {
+ tutorialClass.addStudent(validPerson);
+ tutorialClass.addStudent(validOtherPerson);
+ Index index = Index.fromZeroBased(1);
+ AllocateStudentToTeamByIndexCommand allocateStudentToTeamByIndexCommand = new
+ AllocateStudentToTeamByIndexCommand(index,
+ newModule, tutorialClass, newTeam);
+ assertCommandSuccess(allocateStudentToTeamByIndexCommand, model,
+ String.format(AllocateStudentToTeamByIndexCommand.MESSAGE_SUCCESS, newTeam), model);
+ }
+
+
+ @Test
+ public void invalidAllocationToTeam_studentNotInTutorialClass_failure() {
+ AllocateStudentToTeamByStuIdCommand allocateStudentToTeamByStuIdCommand = new
+ AllocateStudentToTeamByStuIdCommand(validPerson.getStudentId(), newModule, tutorialClass, newTeam);
+ AllocateStudentToTeamByEmailCommand allocateStudentToTeamByEmailCommand = new
+ AllocateStudentToTeamByEmailCommand(validPerson.getEmail(), newModule, tutorialClass, newTeam);
+ assertCommandFailure(allocateStudentToTeamByStuIdCommand, model,
+ String.format(AllocateStudentToTeamCommand.MESSAGE_STUDENT_NOT_IN_TUTORIAL));
+ assertCommandFailure(allocateStudentToTeamByEmailCommand, model,
+ String.format(AllocateStudentToTeamCommand.MESSAGE_STUDENT_NOT_IN_TUTORIAL));
+ }
+
+ @Test
+ public void toString_test() {
+ tutorialClass.addStudent(validPerson);
+ AllocateStudentToTeamByStuIdCommand allocateStudentToTeamByStuIdCommand =
+ new AllocateStudentToTeamByStuIdCommand(validPerson.getStudentId(), newModule, tutorialClass, newTeam);
+ AllocateStudentToTeamByEmailCommand allocateOtherStudentToTeamByEmailCommand =
+ new AllocateStudentToTeamByEmailCommand(validOtherPerson.getEmail(),
+ newModule, tutorialClass, newTeam);
+ AllocateStudentToTeamByIndexCommand allocateStudentToTeamByIndexCommand =
+ new AllocateStudentToTeamByIndexCommand(Index.fromZeroBased(0),
+ newModule, tutorialClass, newTeam);
+ assertEquals(allocateOtherStudentToTeamByEmailCommand.toString(),
+ allocateOtherStudentToTeamByEmailCommand.toString());
+ assertEquals(allocateStudentToTeamByStuIdCommand.toString(),
+ allocateStudentToTeamByStuIdCommand.toString());
+ assertEquals(allocateStudentToTeamByIndexCommand.toString(),
+ allocateStudentToTeamByIndexCommand.toString());
+
+ }
+
+ @Test
+ public void equals() {
+ tutorialClass.addStudent(validPerson);
+ tutorialClass.addStudent(validOtherPerson);
+ // creation of 2 allocation command based on 2 different student ID adding to the same team under
+ // the same module and tutorial class.
+ AllocateStudentToTeamByStuIdCommand allocateStudentToTeamByStuIdCommand =
+ new AllocateStudentToTeamByStuIdCommand(validPerson.getStudentId(), newModule, tutorialClass, newTeam);
+ AllocateStudentToTeamByStuIdCommand allocateOtherStudentToTeamByStuIdCommand =
+ new AllocateStudentToTeamByStuIdCommand(validOtherPerson.getStudentId(),
+ newModule, tutorialClass, newTeam);
+
+ // same object --> returns true
+ assertTrue(allocateStudentToTeamByStuIdCommand.equals(allocateStudentToTeamByStuIdCommand));
+
+ // different type --> returns false
+ assertFalse(allocateStudentToTeamByStuIdCommand.equals("hello world"));
+
+ // null --> returns false
+ assertFalse(allocateStudentToTeamByStuIdCommand.equals(null));
+
+ // allocation of a different person --> returns false
+ assertFalse(allocateStudentToTeamByStuIdCommand.equals(allocateOtherStudentToTeamByStuIdCommand));
+
+ // creation of 2 allocation command based on 2 different student emails adding to the same team under
+ // the same module and tutorial class.
+ AllocateStudentToTeamByEmailCommand allocateStudentToTeamByEmailCommand =
+ new AllocateStudentToTeamByEmailCommand(validPerson.getEmail(), newModule, tutorialClass, newTeam);
+ AllocateStudentToTeamByEmailCommand allocateOtherStudentToTeamByEmailCommand =
+ new AllocateStudentToTeamByEmailCommand(validOtherPerson.getEmail(),
+ newModule, tutorialClass, newTeam);
+
+ // same object --> returns true
+ assertTrue(allocateStudentToTeamByEmailCommand.equals(allocateStudentToTeamByEmailCommand));
+
+ // different type --> returns false
+ assertFalse(allocateStudentToTeamByEmailCommand.equals("hello world"));
+
+ // null --> returns false
+ assertFalse(allocateStudentToTeamByEmailCommand.equals(null));
+
+ // allocation of a different person --> returns false
+ assertFalse(allocateStudentToTeamByEmailCommand.equals(allocateOtherStudentToTeamByEmailCommand));
+
+
+ AllocateStudentToTeamByIndexCommand allocateOtherStudentToTeamByIndexCommand =
+ new AllocateStudentToTeamByIndexCommand(Index.fromZeroBased(1),
+ newModule, tutorialClass, newTeam);
+
+ // same object
+ assertTrue(allocateOtherStudentToTeamByIndexCommand.equals(allocateOtherStudentToTeamByIndexCommand));
+
+ // different type --> returns false
+ assertFalse(allocateOtherStudentToTeamByIndexCommand.equals("hello world"));
+
+ // null --> returns false
+ assertFalse(allocateOtherStudentToTeamByIndexCommand.equals(null));
+ }
+
+}
diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java
index 5599bf61c76..d801560be1a 100644
--- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java
+++ b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java
@@ -34,13 +34,16 @@ public class CommandTestUtil {
public static final String VALID_NAME_BOB = "Bob Choo";
public static final String VALID_EMAIL_AMY = "amy@example.com";
public static final String VALID_EMAIL_BOB = "bob@example.com";
+ public static final String VALID_EMAIL = "c@example.com";
public static final String VALID_STUDENT_ID_AMY = "A1111111Z";
public static final String VALID_STUDENT_ID_BOB = "A2222222Z";
+ public static final String VALID_STUDENT_ID = "A3333333Z";
public static final String VALID_MODULE_AMY = "CS1101S";
public static final String VALID_MODULE_BOB = "CS1231S";
public static final String VALID_TUTORIAL_AMY = "T01";
public static final String VALID_TUTORIAL_BOB = "T02";
+ public static final String VALID_TEAM_NAME = "Team 1";
public static final String VALID_TAG_HUSBAND = "husband";
public static final String VALID_TAG_FRIEND = "friend";
@@ -61,10 +64,13 @@ public class CommandTestUtil {
public static final String INVALID_PERSON_EMAIL = "test@example.com";
public static final String INVALID_PERSON_STUDENT_ID = "A2222222A";
+ public static final String INVALID_MODULECODE = "22JK";
+ public static final String INVALID_TUTORIAL = "HHHH@";
// Team related constants
public static final String VALID_TEAM_NAME_AMY = "Team 1";
public static final String VALID_TEAM_NAME_BOB = "Team 2";
+ public static final String VALID_TEAM_NAME_NEW = "Team 3";
public static final int VALID_TEAM_SIZE = 5;
public static final String TEAM_NAME_DESC_AMY = " " + PREFIX_NAME + VALID_TEAM_NAME_AMY;
public static final String TEAM_SIZE_DESC = " " + PREFIX_TEAM_SIZE + VALID_TEAM_SIZE;
diff --git a/src/test/java/seedu/address/logic/parser/AllocateStudentToTeamCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AllocateStudentToTeamCommandParserTest.java
new file mode 100644
index 00000000000..e660d6c6a74
--- /dev/null
+++ b/src/test/java/seedu/address/logic/parser/AllocateStudentToTeamCommandParserTest.java
@@ -0,0 +1,58 @@
+package seedu.address.logic.parser;
+
+import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TEAM_NAME;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULECODE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_STUDENTID;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_TEAMNAME;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_TUTORIALCLASS;
+import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
+import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;
+import static seedu.address.model.module.ModuleCodeTest.VALID_MODULE_CODE;
+import static seedu.address.model.module.ModuleCodeTest.VALID_TUTORIAL_1;
+import static seedu.address.testutil.TypicalPersons.AMY;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamByEmailCommand;
+import seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamByStuIdCommand;
+import seedu.address.logic.commands.allocatestudenttoteamcommands.AllocateStudentToTeamCommand;
+import seedu.address.model.module.ModuleCode;
+import seedu.address.model.module.TutorialClass;
+import seedu.address.model.module.TutorialTeam;
+import seedu.address.model.person.Person;
+import seedu.address.testutil.PersonBuilder;
+
+public class AllocateStudentToTeamCommandParserTest {
+ private AllocateStudentToTeamCommandParser parser = new AllocateStudentToTeamCommandParser();
+
+ @Test
+ public void parse_validArgs_returnsAllocateStudentToTeamCommand() {
+ Person person = new PersonBuilder(AMY).build();
+ ModuleCode moduleCode = new ModuleCode(VALID_MODULE_CODE);
+ TutorialClass tutorialClass = new TutorialClass(VALID_TUTORIAL_1);
+ TutorialTeam tutorialTeam = new TutorialTeam(VALID_TEAM_NAME);
+ moduleCode.addTutorialClass(tutorialClass);
+ tutorialClass.addTeam(tutorialTeam);
+ AllocateStudentToTeamByStuIdCommand allocateStudentToTeamByStuIdCommand =
+ new AllocateStudentToTeamByStuIdCommand(person.getStudentId(), moduleCode, tutorialClass, tutorialTeam);
+ AllocateStudentToTeamByEmailCommand allocateStudentToTeamByEmailCommand =
+ new AllocateStudentToTeamByEmailCommand(person.getEmail(), moduleCode, tutorialClass, tutorialTeam);
+ String userInput = " " + PREFIX_MODULECODE + moduleCode.moduleCode
+ + " " + PREFIX_TUTORIALCLASS + tutorialClass.tutorialName
+ + " " + PREFIX_TEAMNAME + tutorialTeam.getTeamName();
+ assertParseSuccess(parser, " " + PREFIX_STUDENTID + person.getStudentId().value + userInput,
+ allocateStudentToTeamByStuIdCommand);
+ assertParseSuccess(parser, " " + PREFIX_EMAIL + person.getEmail().value + userInput,
+ allocateStudentToTeamByEmailCommand);
+ }
+
+ @Test
+ public void parse_invalidArgs_throwsParseException() {
+ String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT,
+ AllocateStudentToTeamCommand.MESSAGE_USAGE);
+ assertParseFailure(parser, "a", expectedMessage);
+ }
+
+}
diff --git a/src/test/java/seedu/address/model/AddressBookTest.java b/src/test/java/seedu/address/model/AddressBookTest.java
index 90d1792241a..f31dd2dafd4 100644
--- a/src/test/java/seedu/address/model/AddressBookTest.java
+++ b/src/test/java/seedu/address/model/AddressBookTest.java
@@ -6,6 +6,10 @@
import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY;
import static seedu.address.logic.commands.CommandTestUtil.VALID_STUDENT_ID_AMY;
import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TEAM_NAME;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TEAM_NAME_AMY;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TEAM_NAME_BOB;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TUTORIAL_AMY;
import static seedu.address.testutil.Assert.assertThrows;
import static seedu.address.testutil.TypicalPersons.ALICE;
import static seedu.address.testutil.TypicalPersons.AMY;
@@ -25,6 +29,7 @@
import seedu.address.model.module.TutorialClass;
import seedu.address.model.module.TutorialTeam;
import seedu.address.model.person.Person;
+import seedu.address.model.person.UniquePersonList;
import seedu.address.model.person.exceptions.DuplicatePersonException;
import seedu.address.testutil.PersonBuilder;
@@ -102,6 +107,108 @@ public void hasPersonWithEmail_personNotInAddressBook_returnsFalse() {
assertFalse(addressBook.hasPersonWithEmail(AMY.getEmail()));
}
+ @Test
+ public void isStudentInTutorialClass_personNotInClass_failure() {
+ Person person = new PersonBuilder(ALICE).build();
+ TutorialClass tutorialClass = new TutorialClass(VALID_TUTORIAL_AMY);
+ assertFalse(addressBook.isStudentInTutorialClass(person, tutorialClass));
+ }
+
+ @Test
+ public void isStudentInTutorialClass_classIsNull_failure() {
+ Person person = new PersonBuilder(ALICE).build();
+ assertThrows(NullPointerException.class, () -> addressBook.isStudentInTutorialClass(person, null));
+ }
+
+ @Test
+ public void isStudentInTutorialClass_personIsNull_failure() {
+ TutorialClass tutorialClass = new TutorialClass(VALID_TUTORIAL_AMY);
+ assertThrows(NullPointerException.class, () -> addressBook.isStudentInTutorialClass(null, tutorialClass));
+ }
+
+ @Test
+ public void allocateStudentToTeam_personIsNull_failure() {
+ TutorialTeam tutorialTeam = new TutorialTeam(VALID_TEAM_NAME);
+ assertThrows(NullPointerException.class, () -> addressBook.allocateStudentToTeam(null, tutorialTeam));
+ }
+
+ @Test
+ public void allocateStudentToTeam_tutorialTeamIsNull_failure() {
+ Person person = new PersonBuilder(ALICE).build();
+ assertThrows(NullPointerException.class, () -> addressBook.allocateStudentToTeam(person, null));
+ }
+
+ @Test
+ public void hasTeamSizeExceeded_teamSizeNotExceeded_failure() {
+ TutorialTeam tutorialTeam = new TutorialTeam(VALID_TEAM_NAME, 3);
+ assertFalse(addressBook.hasTeamSizeExceeded(tutorialTeam));
+ }
+
+ @Test
+ public void hasTeamSizeExceeded_teamSizeExceeded_success() {
+ TutorialTeam tutorialTeam = new TutorialTeam(VALID_TEAM_NAME, 1);
+ Person student = new PersonBuilder(ALICE).build();
+ tutorialTeam.addStudent(student);
+ assertTrue(addressBook.hasTeamSizeExceeded(tutorialTeam));
+ }
+
+ @Test
+ public void isStudentInAnyTeam_studentNotInAny_failure() {
+ TutorialClass tutorialClass = new TutorialClass();
+ TutorialTeam firstTutorialTeam = new TutorialTeam(VALID_TEAM_NAME, 1);
+ TutorialTeam secondtutorialTeam = new TutorialTeam(VALID_TEAM_NAME_BOB, 2);
+ tutorialClass.addTeam(firstTutorialTeam);
+ tutorialClass.addTeam(secondtutorialTeam);
+ Person person = new PersonBuilder(ALICE).build();
+ assertFalse(addressBook.isStudentInAnyTeam(person, tutorialClass));
+ }
+
+ @Test
+ public void isStudentInAnyTeam_studentIsNull_failure() {
+ TutorialClass tutorialClass = new TutorialClass(VALID_TUTORIAL_AMY);
+ TutorialTeam firstTutorialTeam = new TutorialTeam(VALID_TEAM_NAME_AMY, 1);
+ TutorialTeam secondtutorialTeam = new TutorialTeam(VALID_TEAM_NAME_BOB, 2);
+ tutorialClass.addTeam(firstTutorialTeam);
+ tutorialClass.addTeam(secondtutorialTeam);
+ assertFalse(addressBook.isStudentInAnyTeam(null, tutorialClass));
+ }
+
+ @Test
+ public void hasTeamInTutorial_success() {
+ TutorialClass tutorialClass = new TutorialClass(VALID_TUTORIAL_AMY);
+ TutorialTeam firstTutorialTeam = new TutorialTeam(VALID_TEAM_NAME, 1);
+ TutorialTeam secondtutorialTeam = new TutorialTeam(VALID_TEAM_NAME_BOB, 2);
+ tutorialClass.addTeam(firstTutorialTeam);
+ tutorialClass.addTeam(secondtutorialTeam);
+ assertTrue(addressBook.hasTeamInTutorial(tutorialClass, firstTutorialTeam));
+ }
+
+ @Test
+ public void hasTeamInTutorial_tutorialTeamIsNull_failure() {
+ TutorialClass tutorialClass = new TutorialClass(VALID_TUTORIAL_AMY);
+ TutorialTeam firstTutorialTeam = new TutorialTeam(VALID_TEAM_NAME, 1);
+ TutorialTeam secondtutorialTeam = new TutorialTeam(VALID_TEAM_NAME_BOB, 2);
+ tutorialClass.addTeam(firstTutorialTeam);
+ tutorialClass.addTeam(secondtutorialTeam);
+ assertThrows(NullPointerException.class, () -> addressBook.hasTeamInTutorial(tutorialClass, null));
+ }
+
+ @Test
+ public void getTutorialTeam_tutorialTeamIsNull_failure() {
+ TutorialClass tutorialClass = new TutorialClass(VALID_TUTORIAL_AMY);
+ assertThrows(NullPointerException.class, () -> addressBook.getTutorialTeam(tutorialClass, null));
+ }
+
+ @Test
+ public void getTutorialTeam_tutorialTeamMatch_success() {
+ TutorialClass tutorialClass = new TutorialClass(VALID_TUTORIAL_AMY);
+ TutorialTeam firstTutorialTeam = new TutorialTeam(VALID_TEAM_NAME, 1);
+ TutorialTeam secondtutorialTeam = new TutorialTeam(VALID_TEAM_NAME_BOB, 2);
+ tutorialClass.addTeam(firstTutorialTeam);
+ tutorialClass.addTeam(secondtutorialTeam);
+ assertEquals(addressBook.getTutorialTeam(tutorialClass, firstTutorialTeam), firstTutorialTeam);
+ }
+
@Test
public void hasPersonWithEmail_differentPersonWithSameEmail_returnsTrue() {
addressBook.addPerson(AMY);
@@ -198,5 +305,24 @@ public ObservableList getTutorialList() {
public ObservableList getTeamList() {
return null;
}
+ @Override
+ public ObservableList getStudentsInTeamList() {
+ return null;
+ }
+
+ @Override
+ public ObservableList getStudentsInTutorialClass(TutorialClass tutorialClass) {
+ return null;
+ }
+
+ @Override
+ public UniquePersonList getUniquePersonList() {
+ return null;
+ }
+
+ @Override
+ public ObservableList getTutorialTeamList() {
+ return null;
+ }
}
}
diff --git a/src/test/java/seedu/address/storage/JsonAdaptedTutorialClassTest.java b/src/test/java/seedu/address/storage/JsonAdaptedTutorialClassTest.java
index 9f5680e1ad6..80eb9ca88f3 100644
--- a/src/test/java/seedu/address/storage/JsonAdaptedTutorialClassTest.java
+++ b/src/test/java/seedu/address/storage/JsonAdaptedTutorialClassTest.java
@@ -10,6 +10,7 @@
import org.junit.jupiter.api.Test;
+import seedu.address.commons.exceptions.IllegalValueException;
import seedu.address.model.module.TutorialClass;
import seedu.address.testutil.PersonBuilder;
@@ -31,12 +32,19 @@ void toModelType_success() throws Exception {
assertEquals(tutorialClass, jsonTutorialClass.toModelType());
}
+ @Test
+ void toModelType_test_success() throws Exception {
+ TutorialClass tutorialClass = new TutorialClass(VALID_TUTORIAL_NAME);
+ JsonAdaptedTutorialClass jsonTutorialClass = new JsonAdaptedTutorialClass(tutorialClass);
+ assertEquals(tutorialClass, jsonTutorialClass.toModelType());
+ }
+
@Test
void toModelType_invalidTutorialName_throwsIllegalValueException() {
JsonAdaptedTutorialClass jsonTutorialClass = new JsonAdaptedTutorialClass(INVALID_TUTORIAL_NAME,
VALID_TEAMS_LIST, VALID_STUDENTS_LIST);
String expectedMessage = TutorialClass.MESSAGE_CONSTRAINTS;
- assertThrows(IllegalArgumentException.class, expectedMessage, jsonTutorialClass::toModelType);
+ assertThrows(IllegalValueException.class, expectedMessage, jsonTutorialClass::toModelType);
}
}
diff --git a/src/test/java/seedu/address/storage/JsonAdaptedTutorialTeamTest.java b/src/test/java/seedu/address/storage/JsonAdaptedTutorialTeamTest.java
index c5a642c91e9..1fb1ec567f6 100644
--- a/src/test/java/seedu/address/storage/JsonAdaptedTutorialTeamTest.java
+++ b/src/test/java/seedu/address/storage/JsonAdaptedTutorialTeamTest.java
@@ -10,6 +10,7 @@
import org.junit.jupiter.api.Test;
+import seedu.address.commons.exceptions.IllegalValueException;
import seedu.address.model.module.TutorialTeam;
import seedu.address.testutil.PersonBuilder;
@@ -31,12 +32,19 @@ void toModelType_success() throws Exception {
assertEquals(tutorialTeam, jsonTutorialTeam.toModelType());
}
+ @Test
+ void toModelType_test_success() throws Exception {
+ TutorialTeam tutorialTeam = new TutorialTeam(VALID_TEAM_NAME, VALID_TEAM_SIZE);
+ JsonAdaptedTutorialTeam jsonTutorialTeam = new JsonAdaptedTutorialTeam(tutorialTeam);
+ assertEquals(tutorialTeam, jsonTutorialTeam.toModelType());
+ }
+
@Test
void toModelType_invalidTeamName_throwsIllegalValueException() {
JsonAdaptedTutorialTeam jsonTutorialTeam = new JsonAdaptedTutorialTeam(INVALID_TEAM_NAME, VALID_TEAM_SIZE,
VALID_STUDENTS_LIST);
String expectedMessage = TutorialTeam.MESSAGE_NAME_CONSTRAINTS;
- assertThrows(IllegalArgumentException.class, expectedMessage, jsonTutorialTeam::toModelType);
+ assertThrows(IllegalValueException.class, expectedMessage, jsonTutorialTeam::toModelType);
}
@Test
@@ -44,7 +52,7 @@ void toModelType_invalidTeamSize_throwsIllegalValueException() {
JsonAdaptedTutorialTeam jsonTutorialTeam = new JsonAdaptedTutorialTeam(VALID_TEAM_NAME, INVALID_TEAM_SIZE,
VALID_STUDENTS_LIST);
String expectedMessage = TutorialTeam.MESSAGE_SIZE_CONSTRAINTS;
- assertThrows(IllegalArgumentException.class, expectedMessage, jsonTutorialTeam::toModelType);
+ assertThrows(IllegalValueException.class, expectedMessage, jsonTutorialTeam::toModelType);
}
}