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); } }