From cf345835caeb84fd87f4f2bf48271ac6475e6e27 Mon Sep 17 00:00:00 2001 From: Jajared Date: Mon, 18 Mar 2024 14:26:27 +0800 Subject: [PATCH 01/33] feat: Add link students to class command --- .../AddStudentToClassByEmailCommand.java | 75 ++++++++++++++++++ .../AddStudentToClassByIdCommand.java | 70 +++++++++++++++++ .../AddStudentToClassByIndexCommand.java | 67 ++++++++++++++++ .../AddStudentToClassCommand.java | 68 ++++++++++++++++ .../DeleteStudentByEmailCommand.java | 5 +- .../DeleteStudentByIdCommand.java | 6 +- .../DeleteStudentByIndexCommand.java | 7 +- .../logic/messages/ModuleMessages.java | 9 +++ .../logic/messages/PersonMessages.java | 15 ++++ .../logic/messages/TutorialClassMessages.java | 11 +++ .../AddStudentToClassCommandParser.java | 77 +++++++++++++++++++ .../model/module/ModuleTutorialPair.java | 40 ++++++++++ .../address/model/module/TutorialClass.java | 31 ++++++-- .../DeleteStudentCommandIntegrationTest.java | 3 +- 14 files changed, 466 insertions(+), 18 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java create mode 100644 src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java create mode 100644 src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java create mode 100644 src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java create mode 100644 src/main/java/seedu/address/logic/messages/ModuleMessages.java create mode 100644 src/main/java/seedu/address/logic/messages/PersonMessages.java create mode 100644 src/main/java/seedu/address/logic/messages/TutorialClassMessages.java create mode 100644 src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java create mode 100644 src/main/java/seedu/address/model/module/ModuleTutorialPair.java diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java new file mode 100644 index 00000000000..6fabd981910 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java @@ -0,0 +1,75 @@ +package seedu.address.logic.commands.addstudenttoclasscommands; + +import static java.util.Objects.requireNonNull; + +import java.util.function.Predicate; + +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.messages.PersonMessages; +import seedu.address.logic.messages.TutorialClassMessages; +import seedu.address.model.Model; +import seedu.address.model.module.ModuleCode; +import seedu.address.model.module.ModuleTutorialPair; +import seedu.address.model.module.TutorialClass; +import seedu.address.model.person.Email; +import seedu.address.model.person.Person; + +/** + * Adds a student to a class by email. + */ +public class AddStudentToClassByEmailCommand extends AddStudentToClassCommand { + + private final Predicate predicate; + + private final Email email; + + /** + * Adds a student to a class by email. + * @param email + * @param module + * @param tutorialClass + */ + public AddStudentToClassByEmailCommand(Email email, ModuleCode module, TutorialClass tutorialClass) { + super(module, tutorialClass); + this.email = email; + this.predicate = person -> person.getEmail().equals(email); + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + ModuleTutorialPair moduleAndTutorialClass = getModuleAndTutorialClass(model); + TutorialClass tutorialClass = moduleAndTutorialClass.getTutorialClass(); + ModuleCode module = moduleAndTutorialClass.getModule(); + Person personToAdd; + personToAdd = model.searchPersonByPredicate(predicate); + if (personToAdd == null) { + throw new CommandException(String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, email)); + } + if (tutorialClass.hasStudent(personToAdd)) { + throw new CommandException( + String.format(TutorialClassMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, personToAdd, + tutorialClass)); + } else { + tutorialClass.addStudent(personToAdd); + return new CommandResult( + String.format(TutorialClassMessages.MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS, personToAdd, module, + tutorialClass)); + } + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof AddStudentToClassByEmailCommand)) { + return false; + } + + AddStudentToClassByEmailCommand otherAddCommand = (AddStudentToClassByEmailCommand) other; + return email.equals(otherAddCommand.email); + } +} diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java new file mode 100644 index 00000000000..54cf1b45247 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java @@ -0,0 +1,70 @@ +package seedu.address.logic.commands.addstudenttoclasscommands; + +import static java.util.Objects.requireNonNull; + +import java.util.function.Predicate; + +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.messages.PersonMessages; +import seedu.address.model.Model; +import seedu.address.model.module.ModuleCode; +import seedu.address.model.module.ModuleTutorialPair; +import seedu.address.model.module.TutorialClass; +import seedu.address.model.person.Person; +import seedu.address.model.person.StudentId; + +/** + * Adds a student to a class by student id. + */ +public class AddStudentToClassByIdCommand extends AddStudentToClassCommand { + + private final Predicate predicate; + + private final StudentId studentId; + + /** + * Adds a student to a class by student id. + * @param studentId + * @param module + * @param tutorialClass + */ + public AddStudentToClassByIdCommand(StudentId studentId, ModuleCode module, TutorialClass tutorialClass) { + super(module, tutorialClass); + this.studentId = studentId; + this.predicate = person -> person.getStudentId().equals(studentId); + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + ModuleTutorialPair moduleAndTutorialClass = getModuleAndTutorialClass(model); + TutorialClass tutorialClass = moduleAndTutorialClass.getTutorialClass(); + Person personToAdd; + personToAdd = model.searchPersonByPredicate(predicate); + if (personToAdd == null) { + throw new CommandException(String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, studentId)); + } + if (tutorialClass.hasStudent(personToAdd)) { + throw new CommandException(String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, personToAdd, + tutorialClass)); + } else { + tutorialClass.addStudent(personToAdd); + return new CommandResult(String.format(PersonMessages.MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS, personToAdd)); + } + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof AddStudentToClassByIdCommand)) { + return false; + } + + AddStudentToClassByIdCommand otherAddCommand = (AddStudentToClassByIdCommand) other; + return studentId.equals(otherAddCommand.studentId); + } +} diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java new file mode 100644 index 00000000000..7de78f050a0 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java @@ -0,0 +1,67 @@ +package seedu.address.logic.commands.addstudenttoclasscommands; + +import static java.util.Objects.requireNonNull; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.messages.PersonMessages; +import seedu.address.model.Model; +import seedu.address.model.module.ModuleCode; +import seedu.address.model.module.ModuleTutorialPair; +import seedu.address.model.module.TutorialClass; +import seedu.address.model.person.Person; + +/** + * Adds a student to a class by index. + */ +public class AddStudentToClassByIndexCommand extends AddStudentToClassCommand { + + private final Index targetIndex; + + /** + * Adds a student to a class by index. + * @param targetIndex + * @param module + * @param tutorialClass + */ + public AddStudentToClassByIndexCommand(Index targetIndex, ModuleCode module, TutorialClass tutorialClass) { + super(module, tutorialClass); + this.targetIndex = targetIndex; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + ModuleTutorialPair moduleAndTutorialClass = getModuleAndTutorialClass(model); + TutorialClass tutorialClass = moduleAndTutorialClass.getTutorialClass(); + Person personToAdd; + try { + personToAdd = model.getFilteredPersonList().get(targetIndex.getZeroBased()); + } catch (IndexOutOfBoundsException e) { + throw new CommandException( + String.format(PersonMessages.MESSAGE_PERSON_INDEX_NOT_FOUND, targetIndex.getOneBased())); + } + if (tutorialClass.hasStudent(personToAdd)) { + throw new CommandException(String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, personToAdd, + tutorialClass)); + } else { + tutorialClass.addStudent(personToAdd); + return new CommandResult(String.format(PersonMessages.MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS, personToAdd)); + } + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof AddStudentToClassByIdCommand)) { + return false; + } + + AddStudentToClassByIndexCommand otherAddCommand = (AddStudentToClassByIndexCommand) other; + return targetIndex.equals(otherAddCommand.targetIndex); + } +} diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java new file mode 100644 index 00000000000..ef7087123c3 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java @@ -0,0 +1,68 @@ +package seedu.address.logic.commands.addstudenttoclasscommands; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULECODE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TUTORIALCLASS; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.messages.ModuleMessages; +import seedu.address.logic.messages.TutorialClassMessages; +import seedu.address.model.Model; +import seedu.address.model.module.ModuleCode; +import seedu.address.model.module.ModuleTutorialPair; +import seedu.address.model.module.TutorialClass; + +/** + * A class that handles the /add_student_to_class command execution. + */ +public abstract class AddStudentToClassCommand extends Command { + public static final String COMMAND_WORD = "/add_student_to_class"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a student to an existing class\n" + + "Parameters:" + PREFIX_MODULECODE + "MODULE_CODE (must be a String) " + + PREFIX_TUTORIALCLASS + "TUTORIAL_CLASS (must be a String)" + + "Example: " + COMMAND_WORD + PREFIX_MODULECODE + " CS2103T " + + PREFIX_TUTORIALCLASS + "T09"; + + private final ModuleCode module; + private final TutorialClass tutorialClass; + + /** + * @param module of the tutorial class to be added + */ + public AddStudentToClassCommand(ModuleCode module, TutorialClass tutorialClass) { + requireAllNonNull(module, tutorialClass); + this.module = module; + this.tutorialClass = tutorialClass; + } + + protected ModuleTutorialPair getModuleAndTutorialClass(Model model) throws CommandException { + requireNonNull(model); + ModuleCode module = getModule(); + TutorialClass tutorialClass = getTutorialClass(); + ModuleCode existingModule = model.findModuleFromList(module); + if (existingModule == null) { + throw new CommandException(String.format(ModuleMessages.MESSAGE_MODULE_NOT_FOUND, module)); + } + if (!existingModule.hasTutorialClass(tutorialClass)) { + throw new CommandException( + String.format(TutorialClassMessages.MESSAGE_TUTORIAL_CLASS_NOT_FOUND, tutorialClass)); + } + return new ModuleTutorialPair(module, tutorialClass); + } + + protected ModuleCode getModule() { + return module; + } + + protected TutorialClass getTutorialClass() { + return tutorialClass; + } + + public abstract CommandResult execute(Model model) throws CommandException; + + public abstract boolean equals(Object other); +} diff --git a/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentByEmailCommand.java b/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentByEmailCommand.java index 13327cffee2..d44ca3517ca 100644 --- a/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentByEmailCommand.java +++ b/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentByEmailCommand.java @@ -6,6 +6,7 @@ import seedu.address.logic.Messages; import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.messages.PersonMessages; import seedu.address.model.Model; import seedu.address.model.person.Email; import seedu.address.model.person.Person; @@ -15,8 +16,6 @@ */ public class DeleteStudentByEmailCommand extends DeleteStudentCommand { - public static final String MESSAGE_PERSON_EMAIL_NOT_FOUND = "The student with email %s " - + "does not exist in the address book"; private final Email email; @@ -34,7 +33,7 @@ public CommandResult execute(Model model) throws CommandException { Person personToDelete; personToDelete = model.searchPersonByPredicate(person -> person.getEmail().equals(email)); if (personToDelete == null) { - throw new CommandException(String.format(MESSAGE_PERSON_EMAIL_NOT_FOUND, email)); + throw new CommandException(String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, email)); } model.deletePerson(personToDelete); diff --git a/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentByIdCommand.java b/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentByIdCommand.java index c9a99aba9e4..6dd745a2d33 100644 --- a/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentByIdCommand.java +++ b/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentByIdCommand.java @@ -6,6 +6,7 @@ import seedu.address.logic.Messages; import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.messages.PersonMessages; import seedu.address.model.Model; import seedu.address.model.person.Person; import seedu.address.model.person.StudentId; @@ -15,9 +16,6 @@ */ public class DeleteStudentByIdCommand extends DeleteStudentCommand { - public static final String MESSAGE_PERSON_STUDENT_ID_NOT_FOUND = "The student with student ID %s " - + "does not exist in the address book"; - private final StudentId studentId; /** @@ -34,7 +32,7 @@ public CommandResult execute(Model model) throws CommandException { Person personToDelete; personToDelete = model.searchPersonByPredicate(person -> person.getStudentId().equals(studentId)); if (personToDelete == null) { - throw new CommandException(String.format(MESSAGE_PERSON_STUDENT_ID_NOT_FOUND, studentId)); + throw new CommandException(String.format(PersonMessages.MESSAGE_PERSON_STUDENT_ID_NOT_FOUND, studentId)); } model.deletePerson(personToDelete); diff --git a/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentByIndexCommand.java b/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentByIndexCommand.java index 2559407b494..1b68d7d84f7 100644 --- a/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentByIndexCommand.java +++ b/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentByIndexCommand.java @@ -7,6 +7,7 @@ import seedu.address.logic.Messages; import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.messages.PersonMessages; import seedu.address.model.Model; import seedu.address.model.person.Person; @@ -15,9 +16,6 @@ */ public class DeleteStudentByIndexCommand extends DeleteStudentCommand { - public static final String MESSAGE_PERSON_INDEX_NOT_FOUND = "The student at index %s " - + "does not exist in the address book"; - private final Index targetIndex; /** @@ -35,7 +33,8 @@ public CommandResult execute(Model model) throws CommandException { try { personToDelete = model.getFilteredPersonList().get(targetIndex.getZeroBased()); } catch (IndexOutOfBoundsException e) { - throw new CommandException(String.format(MESSAGE_PERSON_INDEX_NOT_FOUND, targetIndex.getOneBased())); + throw new CommandException(String.format(PersonMessages.MESSAGE_PERSON_INDEX_NOT_FOUND, + targetIndex.getOneBased())); } model.deletePerson(personToDelete); diff --git a/src/main/java/seedu/address/logic/messages/ModuleMessages.java b/src/main/java/seedu/address/logic/messages/ModuleMessages.java new file mode 100644 index 00000000000..5aa0d3bbc04 --- /dev/null +++ b/src/main/java/seedu/address/logic/messages/ModuleMessages.java @@ -0,0 +1,9 @@ +package seedu.address.logic.messages; + +/** + * A class that contains all the messages related to the Module class. + */ +public class ModuleMessages { + public static final String MESSAGE_MODULE_NOT_FOUND = "The module with module code %s " + + "does not exist in the address book"; +} diff --git a/src/main/java/seedu/address/logic/messages/PersonMessages.java b/src/main/java/seedu/address/logic/messages/PersonMessages.java new file mode 100644 index 00000000000..f3c2061b8ea --- /dev/null +++ b/src/main/java/seedu/address/logic/messages/PersonMessages.java @@ -0,0 +1,15 @@ +package seedu.address.logic.messages; + +/** + * A class that contains all the messages related to the Person class. + */ +public class PersonMessages { + public static final String MESSAGE_PERSON_STUDENT_ID_NOT_FOUND = "The student with student ID %s " + + "does not exist in the address book"; + public static final String MESSAGE_PERSON_EMAIL_NOT_FOUND = "The student with email %s " + + "does not exist in the address book"; + public static final String MESSAGE_PERSON_INDEX_NOT_FOUND = "The student at index %s " + + "does not exist in the address book"; + public static final String MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS = "Added student %1$s to %2$s %3$s"; + public static final String MESSAGE_DUPLICATE_STUDENT_IN_CLASS = "%1$s already added to %2$s!"; +} diff --git a/src/main/java/seedu/address/logic/messages/TutorialClassMessages.java b/src/main/java/seedu/address/logic/messages/TutorialClassMessages.java new file mode 100644 index 00000000000..529b9d0b15a --- /dev/null +++ b/src/main/java/seedu/address/logic/messages/TutorialClassMessages.java @@ -0,0 +1,11 @@ +package seedu.address.logic.messages; + +/** + * Contains all the messages for TutorialClass related commands + */ +public class TutorialClassMessages { + public static final String MESSAGE_TUTORIAL_CLASS_NOT_FOUND = "The tutorial class with tutorial class code %s " + + "does not exist in the address book"; + public static final String MESSAGE_DUPLICATE_STUDENT_IN_CLASS = "%1$s already added to %2$s!"; + public static final String MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS = "Added student %1$s to %2$s %3$s"; +} diff --git a/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java b/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java new file mode 100644 index 00000000000..61c96405383 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java @@ -0,0 +1,77 @@ +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_TUTORIALCLASS; + +import java.util.stream.Stream; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.AddCommand; +import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByEmailCommand; +import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByIdCommand; +import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByIndexCommand; +import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.module.ModuleCode; +import seedu.address.model.module.TutorialClass; +import seedu.address.model.person.Email; +import seedu.address.model.person.StudentId; + +/** + * Parses input arguments and creates a new AddStudentToClassCommand object + */ +public class AddStudentToClassCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the + * AddStudentToClass + * and returns an AddStudentToClassCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public AddStudentToClassCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_INDEX, PREFIX_EMAIL, PREFIX_STUDENTID, + PREFIX_MODULECODE, PREFIX_TUTORIALCLASS); + boolean isIndexPresent = argMultimap.getValue(PREFIX_INDEX).isPresent(); + boolean isEmailPresent = argMultimap.getValue(PREFIX_EMAIL).isPresent(); + boolean isStudentIdPresent = argMultimap.getValue(PREFIX_STUDENTID).isPresent(); + if (!arePrefixesPresent(argMultimap, PREFIX_MODULECODE, PREFIX_TUTORIALCLASS) && !isIndexPresent + && !isEmailPresent && !isStudentIdPresent + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddStudentToClassCommand.MESSAGE_USAGE)); + } + + argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_INDEX, PREFIX_STUDENTID, PREFIX_EMAIL, + PREFIX_MODULECODE, PREFIX_TUTORIALCLASS); + ModuleCode moduleCode = ParserUtil.parseModuleCode(argMultimap.getValue(PREFIX_MODULECODE).get()); + TutorialClass tutorialClass = ParserUtil.parseTutorialClass(argMultimap.getValue(PREFIX_TUTORIALCLASS).get()); + if (isIndexPresent) { + Index index = ParserUtil.parseIndex(argMultimap.getValue(PREFIX_INDEX).get()); + return new AddStudentToClassByIndexCommand(index, moduleCode, tutorialClass); + } else if (isStudentIdPresent) { + StudentId studentId = ParserUtil.parseStudentId(argMultimap.getValue(PREFIX_STUDENTID).get()); + return new AddStudentToClassByIdCommand(studentId, moduleCode, tutorialClass); + } else if (isEmailPresent) { + Email email = ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get()); + return new AddStudentToClassByEmailCommand(email, moduleCode, tutorialClass); + } else { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE)); + } + + } + + /** + * 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/model/module/ModuleTutorialPair.java b/src/main/java/seedu/address/model/module/ModuleTutorialPair.java new file mode 100644 index 00000000000..b07c70c3662 --- /dev/null +++ b/src/main/java/seedu/address/model/module/ModuleTutorialPair.java @@ -0,0 +1,40 @@ +package seedu.address.model.module; + +/** + * Represents a pair of a module and a tutorial class. + */ +public class ModuleTutorialPair { + private ModuleCode module; + private TutorialClass tutorialClass; + + /** + * Creates a ModuleTutorialPair object. + * @param module The module code. + * @param tutorialClass The tutorial class. + */ + public ModuleTutorialPair(ModuleCode module, TutorialClass tutorialClass) { + this.module = module; + this.tutorialClass = tutorialClass; + } + + /** + * Gets the module code. + * @return The module code. + */ + public ModuleCode getModule() { + return module; + } + + /** + * Gets the tutorial class. + * @return The tutorial class. + */ + public TutorialClass getTutorialClass() { + return tutorialClass; + } + + @Override + public String toString() { + return "(" + module + ", " + tutorialClass + ")"; + } +} diff --git a/src/main/java/seedu/address/model/module/TutorialClass.java b/src/main/java/seedu/address/model/module/TutorialClass.java index 4279a5ec062..34af039b035 100644 --- a/src/main/java/seedu/address/model/module/TutorialClass.java +++ b/src/main/java/seedu/address/model/module/TutorialClass.java @@ -9,12 +9,13 @@ /** * Represents a Module's tutorial class code. - * Guarantees: immutable; is valid as declared in {@link #isValidTutorialClass(String)} + * Guarantees: immutable; is valid as declared in + * {@link #isValidTutorialClass(String)} */ public class TutorialClass { - public static final String MESSAGE_CONSTRAINTS = - "Please enter a valid NUS tutorial class code eg. T01, and it should not be blank"; + public static final String MESSAGE_CONSTRAINTS = "Please enter a valid NUS tutorial class code " + + "eg. T01, and it should not be blank"; /** * This regex validates the tutorial class code that user enters. @@ -26,7 +27,8 @@ public class TutorialClass { private final ArrayList students; /** - * A constructor for TutorialClass. Creates an empty tutorial class with no students. + * A constructor for TutorialClass. Creates an empty tutorial class with no + * students. * * @param name of tutorial to be added */ @@ -38,9 +40,10 @@ public TutorialClass(String name) { } /** - * A constructor for TutorialClass. Creates a tutorial with the list of students specified. + * A constructor for TutorialClass. Creates a tutorial with the list of students + * specified. * - * @param name of tutorial to be added + * @param name of tutorial to be added * @param students to be in the added tutorial */ public TutorialClass(String name, ArrayList students) { @@ -57,6 +60,22 @@ public static boolean isValidTutorialClass(String test) { return test.matches(VALIDATION_REGEX); } + /** + * Adds a student to the tutorial class. + */ + public void addStudent(Person student) { + students.add(student); + } + + /** + * Checks if the student is in the tutorial class. + * @param student + * @return true if the student is in the tutorial class + */ + public boolean hasStudent(Person student) { + return students.contains(student); + } + @Override public String toString() { return value; diff --git a/src/test/java/seedu/address/logic/commands/DeleteStudentCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/DeleteStudentCommandIntegrationTest.java index d4d20a9c19c..6bdca87b950 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteStudentCommandIntegrationTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteStudentCommandIntegrationTest.java @@ -11,6 +11,7 @@ import seedu.address.logic.commands.deletestudentcommands.DeleteStudentByEmailCommand; import seedu.address.logic.commands.deletestudentcommands.DeleteStudentByIdCommand; import seedu.address.logic.commands.deletestudentcommands.DeleteStudentCommand; +import seedu.address.logic.messages.PersonMessages; import seedu.address.model.Model; import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; @@ -71,7 +72,7 @@ public void execute_deleteStudentWithInvalidId_throwsCommandException() { // Attempt to delete the student assertCommandFailure(new DeleteStudentByIdCommand(invalidId), expectedModel, - String.format(DeleteStudentByIdCommand.MESSAGE_PERSON_STUDENT_ID_NOT_FOUND, "A0123456X")); + String.format(PersonMessages.MESSAGE_PERSON_STUDENT_ID_NOT_FOUND, "A0123456X")); } } From c73b49fa5914cede3bae2efdfba3067f4f7eecd3 Mon Sep 17 00:00:00 2001 From: Jajared Date: Mon, 18 Mar 2024 18:08:49 +0800 Subject: [PATCH 02/33] Add test cases --- .../AddStudentToClassByEmailCommand.java | 5 +- .../AddStudentToClassByIdCommand.java | 5 +- .../AddStudentToClassByIndexCommand.java | 7 +- .../AddStudentToClassCommand.java | 7 +- .../DeleteStudentCommand.java | 2 +- .../AddStudentToClassCommandParser.java | 8 +- .../logic/parser/AddressBookParser.java | 4 + .../address/model/module/TutorialClass.java | 3 +- ...dStudentToClassCommandIntegrationTest.java | 94 ++++++++++++ .../AddStudentToClassCommandTest.java | 138 ++++++++++++++++++ 10 files changed, 259 insertions(+), 14 deletions(-) create mode 100644 src/test/java/seedu/address/logic/commands/AddStudentToClassCommandIntegrationTest.java create mode 100644 src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java index 6fabd981910..cabe87b6c75 100644 --- a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java @@ -4,6 +4,7 @@ import java.util.function.Predicate; +import seedu.address.logic.Messages; import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.logic.messages.PersonMessages; @@ -43,6 +44,7 @@ public CommandResult execute(Model model) throws CommandException { TutorialClass tutorialClass = moduleAndTutorialClass.getTutorialClass(); ModuleCode module = moduleAndTutorialClass.getModule(); Person personToAdd; + personToAdd = model.searchPersonByPredicate(predicate); if (personToAdd == null) { throw new CommandException(String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, email)); @@ -54,7 +56,8 @@ public CommandResult execute(Model model) throws CommandException { } else { tutorialClass.addStudent(personToAdd); return new CommandResult( - String.format(TutorialClassMessages.MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS, personToAdd, module, + String.format(TutorialClassMessages.MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS, + Messages.format(personToAdd), module, tutorialClass)); } } diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java index 54cf1b45247..2201917522c 100644 --- a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java @@ -4,6 +4,7 @@ import java.util.function.Predicate; +import seedu.address.logic.Messages; import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.logic.messages.PersonMessages; @@ -39,6 +40,7 @@ public AddStudentToClassByIdCommand(StudentId studentId, ModuleCode module, Tuto public CommandResult execute(Model model) throws CommandException { requireNonNull(model); ModuleTutorialPair moduleAndTutorialClass = getModuleAndTutorialClass(model); + ModuleCode module = moduleAndTutorialClass.getModule(); TutorialClass tutorialClass = moduleAndTutorialClass.getTutorialClass(); Person personToAdd; personToAdd = model.searchPersonByPredicate(predicate); @@ -50,7 +52,8 @@ public CommandResult execute(Model model) throws CommandException { tutorialClass)); } else { tutorialClass.addStudent(personToAdd); - return new CommandResult(String.format(PersonMessages.MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS, personToAdd)); + return new CommandResult(String.format(PersonMessages.MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS, + Messages.format(personToAdd), module, tutorialClass)); } } diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java index 7de78f050a0..96284b94ea5 100644 --- a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java @@ -3,6 +3,7 @@ import static java.util.Objects.requireNonNull; import seedu.address.commons.core.index.Index; +import seedu.address.logic.Messages; import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.logic.messages.PersonMessages; @@ -35,6 +36,7 @@ public CommandResult execute(Model model) throws CommandException { requireNonNull(model); ModuleTutorialPair moduleAndTutorialClass = getModuleAndTutorialClass(model); TutorialClass tutorialClass = moduleAndTutorialClass.getTutorialClass(); + ModuleCode module = moduleAndTutorialClass.getModule(); Person personToAdd; try { personToAdd = model.getFilteredPersonList().get(targetIndex.getZeroBased()); @@ -42,12 +44,15 @@ public CommandResult execute(Model model) throws CommandException { throw new CommandException( String.format(PersonMessages.MESSAGE_PERSON_INDEX_NOT_FOUND, targetIndex.getOneBased())); } + if (tutorialClass.hasStudent(personToAdd)) { throw new CommandException(String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, personToAdd, tutorialClass)); } else { tutorialClass.addStudent(personToAdd); - return new CommandResult(String.format(PersonMessages.MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS, personToAdd)); + return new CommandResult( + String.format(PersonMessages.MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS, + Messages.format(personToAdd), module, tutorialClass)); } } diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java index ef7087123c3..709e105350f 100644 --- a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java @@ -2,6 +2,7 @@ import static java.util.Objects.requireNonNull; import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; +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_TUTORIALCLASS; @@ -22,9 +23,9 @@ public abstract class AddStudentToClassCommand extends Command { public static final String COMMAND_WORD = "/add_student_to_class"; public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a student to an existing class\n" - + "Parameters:" + PREFIX_MODULECODE + "MODULE_CODE (must be a String) " - + PREFIX_TUTORIALCLASS + "TUTORIAL_CLASS (must be a String)" - + "Example: " + COMMAND_WORD + PREFIX_MODULECODE + " CS2103T " + + "Parameters:" + "IDENTIFIER " + PREFIX_MODULECODE + "MODULE_CODE (must be a String) " + + PREFIX_TUTORIALCLASS + "TUTORIAL_CLASS (must be a String)\n" + + "Example: " + COMMAND_WORD + " " + PREFIX_EMAIL + "test@gmail.com " + PREFIX_MODULECODE + " CS2103T " + PREFIX_TUTORIALCLASS + "T09"; private final ModuleCode module; diff --git a/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentCommand.java b/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentCommand.java index 73603041929..959723709e4 100644 --- a/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentCommand.java +++ b/src/main/java/seedu/address/logic/commands/deletestudentcommands/DeleteStudentCommand.java @@ -14,7 +14,7 @@ public abstract class DeleteStudentCommand extends Command { public static final String MESSAGE_USAGE = COMMAND_WORD + ": Deletes the student identified by the student ID or email used in the displayed students list.\n" - + "Parameters: IDENTIFIER (must be a valid student ID or a valid email address)\n" + + "Parameters: IDENTIFIER (must be a index, valid student ID or a valid email address)\n" + "Example: " + COMMAND_WORD + " email/johndoe@gmail.com"; public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Student: %1$s"; diff --git a/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java b/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java index 61c96405383..5d2026e071d 100644 --- a/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java @@ -10,7 +10,6 @@ import java.util.stream.Stream; import seedu.address.commons.core.index.Index; -import seedu.address.logic.commands.AddCommand; import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByEmailCommand; import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByIdCommand; import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByIndexCommand; @@ -28,8 +27,7 @@ public class AddStudentToClassCommandParser implements Parser returns true + assertTrue(addStudentToClassByIndexFirstCommand.equals(addStudentToClassByIndexFirstCommand)); + // different types -> returns false + assertFalse(addStudentToClassByIndexFirstCommand.equals(1)); + + // null -> returns false + assertFalse(addStudentToClassByIndexFirstCommand.equals(null)); + + // different person -> returns false + assertFalse(addStudentToClassByIndexFirstCommand.equals(addStudentToClassByIndexSecondCommand)); + + // Test email based delete command + AddStudentToClassByEmailCommand addStudentToClassByEmailFirstCommand = new AddStudentToClassByEmailCommand( + new Email(VALID_EMAIL_AMY), new ModuleCode(VALID_MODULE_AMY), new TutorialClass(VALID_TUTORIAL_AMY)); + AddStudentToClassByEmailCommand addStudentToClassByEmailSecondCommand = new AddStudentToClassByEmailCommand( + new Email(VALID_EMAIL_BOB), new ModuleCode(VALID_MODULE_BOB), new TutorialClass(VALID_TUTORIAL_BOB)); + + // same object -> returns true + assertTrue(addStudentToClassByEmailFirstCommand.equals(addStudentToClassByEmailFirstCommand)); + // different types -> returns false + assertFalse(addStudentToClassByEmailFirstCommand.equals(1)); + + // null -> returns false + assertFalse(addStudentToClassByEmailFirstCommand.equals(null)); + + // different person -> returns false + assertFalse(addStudentToClassByEmailFirstCommand.equals(addStudentToClassByEmailSecondCommand)); + + // Test student id based delete command + AddStudentToClassByIdCommand addStudentToClassByIdFirstCommand = new AddStudentToClassByIdCommand( + new StudentId(VALID_STUDENT_ID_AMY), new ModuleCode(VALID_MODULE_AMY), + new TutorialClass(VALID_TUTORIAL_AMY)); + AddStudentToClassByIdCommand addStudentToClassByIdSecondCommand = new AddStudentToClassByIdCommand( + new StudentId(VALID_STUDENT_ID_BOB), new ModuleCode(VALID_MODULE_BOB), + new TutorialClass(VALID_TUTORIAL_BOB)); + + // same object -> returns true + assertTrue(addStudentToClassByIdFirstCommand.equals(addStudentToClassByIdFirstCommand)); + // different types -> returns false + assertFalse(addStudentToClassByIdFirstCommand.equals(1)); + // null -> returns false + assertFalse(addStudentToClassByIdFirstCommand.equals(null)); + // different person -> returns false + assertFalse(addStudentToClassByIdFirstCommand.equals(addStudentToClassByIdSecondCommand)); + + } + + /** + * Updates {@code model}'s filtered list to show no one. + */ + private void showNoPerson(Model model) { + model.updateFilteredPersonList(p -> false); + + assertTrue(model.getFilteredPersonList().isEmpty()); + } +} From ad36a1d4dfd836a2b2423a6db82c313d441bc5af Mon Sep 17 00:00:00 2001 From: Jajared Date: Mon, 18 Mar 2024 18:29:09 +0800 Subject: [PATCH 03/33] Add more unit test cases --- .../AddStudentToClassCommandTest.java | 60 +++++++------------ .../logic/commands/CommandTestUtil.java | 3 + 2 files changed, 24 insertions(+), 39 deletions(-) diff --git a/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java b/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java index 57dcf858d54..577d431b9eb 100644 --- a/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java @@ -2,6 +2,8 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.address.logic.commands.CommandTestUtil.INVALID_EMAIL; +import static seedu.address.logic.commands.CommandTestUtil.INVALID_STUDENT_ID; import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY; import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB; import static seedu.address.logic.commands.CommandTestUtil.VALID_MODULE_AMY; @@ -10,27 +12,24 @@ import static seedu.address.logic.commands.CommandTestUtil.VALID_STUDENT_ID_BOB; import static seedu.address.logic.commands.CommandTestUtil.VALID_TUTORIAL_AMY; import static seedu.address.logic.commands.CommandTestUtil.VALID_TUTORIAL_BOB; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON; import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import seedu.address.logic.Messages; import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByEmailCommand; import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByIdCommand; import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByIndexCommand; -import seedu.address.logic.commands.deletestudentcommands.DeleteStudentByIndexCommand; -import seedu.address.logic.commands.deletestudentcommands.DeleteStudentCommand; +import seedu.address.logic.messages.PersonMessages; 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.person.Email; -import seedu.address.model.person.Person; import seedu.address.model.person.StudentId; /** @@ -41,35 +40,27 @@ public class AddStudentToClassCommandTest { private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); - @Test - public void execute_validIndexUnfilteredList_success() { - Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); - DeleteStudentCommand deleteCommand = new DeleteStudentByIndexCommand(INDEX_FIRST_PERSON); - - String expectedMessage = String.format(DeleteStudentCommand.MESSAGE_DELETE_PERSON_SUCCESS, - Messages.format(personToDelete)); - - ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); - expectedModel.deletePerson(personToDelete); - - assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel); + @BeforeEach + public void setUp() { + ModuleCode newModule = new ModuleCode(VALID_MODULE_AMY); + model.addModule(newModule); + TutorialClass newTutorialClass = new TutorialClass(VALID_TUTORIAL_AMY); + newModule.addTutorialClass(newTutorialClass); } @Test - public void execute_validIndexFilteredList_success() { - showPersonAtIndex(model, INDEX_FIRST_PERSON); - - Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); - DeleteStudentCommand deleteCommand = new DeleteStudentByIndexCommand(INDEX_FIRST_PERSON); - - String expectedMessage = String.format(DeleteStudentCommand.MESSAGE_DELETE_PERSON_SUCCESS, - Messages.format(personToDelete)); + public void execute_invalidStudent_fail() { + AddStudentToClassByEmailCommand addStudentToClassByEmailCommand = new AddStudentToClassByEmailCommand( + new Email(INVALID_EMAIL), new ModuleCode(VALID_MODULE_AMY), new TutorialClass(VALID_TUTORIAL_AMY)); + AddStudentToClassByIdCommand addStudentToClassByIdCommand = new AddStudentToClassByIdCommand( + new StudentId(INVALID_STUDENT_ID), new ModuleCode(VALID_MODULE_AMY), + new TutorialClass(VALID_TUTORIAL_AMY)); - Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); - expectedModel.deletePerson(personToDelete); - showNoPerson(expectedModel); + assertCommandFailure(addStudentToClassByEmailCommand, model, + String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, INVALID_EMAIL)); + assertCommandFailure(addStudentToClassByIdCommand, model, + String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, INVALID_STUDENT_ID)); - assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel); } @Test @@ -126,13 +117,4 @@ public void equals() { assertFalse(addStudentToClassByIdFirstCommand.equals(addStudentToClassByIdSecondCommand)); } - - /** - * Updates {@code model}'s filtered list to show no one. - */ - private void showNoPerson(Model model) { - model.updateFilteredPersonList(p -> false); - - assertTrue(model.getFilteredPersonList().isEmpty()); - } } diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java index f1e1fb73345..fa7379420a4 100644 --- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java +++ b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java @@ -60,6 +60,9 @@ public class CommandTestUtil { public static final String TAG_DESC_FRIEND = " " + PREFIX_TAG + VALID_TAG_FRIEND; public static final String TAG_DESC_HUSBAND = " " + PREFIX_TAG + VALID_TAG_HUSBAND; + public static final String INVALID_EMAIL = "test@example.com"; + public static final String INVALID_STUDENT_ID = "A2222222A"; + // '&' not allowed in names public static final String INVALID_NAME_DESC = " " + PREFIX_NAME + "James&"; From 2a9084e3eb777cca5ca61b5f381b3292e17fe3d2 Mon Sep 17 00:00:00 2001 From: Jajared Date: Mon, 18 Mar 2024 19:59:44 +0800 Subject: [PATCH 04/33] Add parser test --- .../AddStudentToClassCommandParser.java | 7 ++- .../AddStudentToClassCommandTest.java | 19 ++++++- .../AddStudentToClassCommandParserTest.java | 57 +++++++++++++++++++ 3 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 src/test/java/seedu/address/logic/parser/AddStudentToClassCommandParserTest.java diff --git a/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java b/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java index 5d2026e071d..20c7f5e4985 100644 --- a/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java @@ -27,7 +27,8 @@ public class AddStudentToClassCommandParser implements Parser Date: Mon, 18 Mar 2024 22:42:34 +0800 Subject: [PATCH 05/33] Add delete_class functionality --- .../logic/commands/AddClassCommand.java | 4 +- .../logic/commands/DeleteClassCommand.java | 83 +++++++++++++++++++ .../logic/parser/AddressBookParser.java | 4 + .../parser/DeleteClassCommandParser.java | 49 +++++++++++ .../address/model/module/ModuleCode.java | 31 +++++++ .../logic/commands/AddClassCommandTest.java | 6 +- .../commands/DeleteClassCommandTest.java | 4 + .../logic/parser/AddressBookParserTest.java | 12 +++ .../parser/DeleteClassCommandParserTest.java | 4 + 9 files changed, 192 insertions(+), 5 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/DeleteClassCommand.java create mode 100644 src/main/java/seedu/address/logic/parser/DeleteClassCommandParser.java create mode 100644 src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java create mode 100644 src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java diff --git a/src/main/java/seedu/address/logic/commands/AddClassCommand.java b/src/main/java/seedu/address/logic/commands/AddClassCommand.java index a269bbf6219..cfcfa92c930 100644 --- a/src/main/java/seedu/address/logic/commands/AddClassCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddClassCommand.java @@ -14,7 +14,7 @@ * A class that handles the /add_class command execution. */ public class AddClassCommand extends Command { - public static final String MESSAGE_ADD_REMARK_SUCCESS = "Added %1$s %2$s"; + public static final String MESSAGE_ADD_CLASS_SUCCESS = "Added %1$s %2$s"; public static final String MESSAGE_DUPLICATE_CLASS = "%1$s %2$s already added!"; public static final String COMMAND_WORD = "/add_class"; @@ -60,7 +60,7 @@ public CommandResult execute(Model model) throws CommandException { * {@code personToEdit}. */ private String generateSuccessMessage(ModuleCode module, TutorialClass tutorialString) { - return String.format(MESSAGE_ADD_REMARK_SUCCESS, module.toString(), tutorialString.toString()); + return String.format(MESSAGE_ADD_CLASS_SUCCESS, module.toString(), tutorialString.toString()); } @Override diff --git a/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java b/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java new file mode 100644 index 00000000000..8bb54c70c11 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java @@ -0,0 +1,83 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; +import static seedu.address.logic.commands.AddClassCommand.MESSAGE_ADD_CLASS_SUCCESS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULECODE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TUTORIALCLASS; + +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.module.ModuleCode; +import seedu.address.model.module.TutorialClass; + +public class DeleteClassCommand extends Command { + public static final String MESSAGE_DELETE_CLASS_SUCCESS = "Removed %1$s %2$s!"; + public static final String MESSAGE_MODULE_NOT_FOUND = "%1$s not in list!"; + public static final String MESSAGE_CLASS_NOT_FOUND = "%1$s %2$s not in list!"; + public static final String COMMAND_WORD = "/delete_class"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Deletes a class with the module code and tutorial class specified\n" + + "Parameters:" + PREFIX_MODULECODE + "MODULE_CODE (must be a String) " + + PREFIX_TUTORIALCLASS + "TUTORIAL_CLASS (must be a String)" + + "Example: " + COMMAND_WORD + PREFIX_MODULECODE + " CS2103T " + + PREFIX_TUTORIALCLASS + "T09"; + + private final ModuleCode module; + private final TutorialClass tutorialString; + + /** + * @param module of the tutorial class to be added + */ + public DeleteClassCommand(ModuleCode module, TutorialClass tutorialClass) { + requireAllNonNull(module); + this.module = module; + this.tutorialString = tutorialClass; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + ModuleCode existingModule = model.findModuleFromList(module); + if (existingModule == null) { + new ListClassesCommand(); + String moduleNotFoundMessage = String.format(MESSAGE_MODULE_NOT_FOUND, module); + throw new CommandException(moduleNotFoundMessage); + } + + if (!(existingModule.hasTutorialClass(tutorialString))) { + String classNotFoundMessage = String.format(MESSAGE_CLASS_NOT_FOUND, module, tutorialString); + String tutorialList = existingModule.listTutorialClasses(); + throw new CommandException(classNotFoundMessage + "\n" + tutorialList); + } else { + existingModule.deleteTutorialClass(tutorialString); + } + + return new CommandResult(generateSuccessMessage(module, tutorialString)); + } + + /** + * Generates a command execution success message based on whether the removed from + * {@code personToEdit}. + */ + private String generateSuccessMessage(ModuleCode module, TutorialClass tutorialString) { + return String.format(MESSAGE_DELETE_CLASS_SUCCESS, module.toString(), tutorialString.toString()); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof DeleteClassCommand)) { + return false; + } + + DeleteClassCommand e = (DeleteClassCommand) other; + return module.equals(e.module); + } +} + diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index f63251de5ec..326c9d22737 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -12,6 +12,7 @@ import seedu.address.logic.commands.AddCommand; import seedu.address.logic.commands.ClearCommand; import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.DeleteClassCommand; import seedu.address.logic.commands.DeleteCommand; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.ExitCommand; @@ -70,6 +71,9 @@ public Command parseCommand(String userInput) throws ParseException { case ClearCommand.COMMAND_WORD: return new ClearCommand(); + case DeleteClassCommand.COMMAND_WORD: + return new DeleteClassCommandParser().parse(arguments); + case DeleteStudentCommand.COMMAND_WORD: return new DeleteStudentCommandParser().parse(arguments); diff --git a/src/main/java/seedu/address/logic/parser/DeleteClassCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteClassCommandParser.java new file mode 100644 index 00000000000..75cafed54e7 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/DeleteClassCommandParser.java @@ -0,0 +1,49 @@ +package seedu.address.logic.parser; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULECODE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TUTORIALCLASS; + +import java.util.stream.Stream; + +import seedu.address.logic.commands.DeleteClassCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.module.ModuleCode; +import seedu.address.model.module.TutorialClass; + + + +/** + * Parses input arguments and creates a new {@code RemarkCommand} object + */ +public class DeleteClassCommandParser implements Parser { + /** + * Parses the given {@code String} of arguments in the context of the {@code RemarkCommand} + * and returns a {@code RemarkCommand} object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public DeleteClassCommand parse(String args) throws ParseException { + requireNonNull(args); + ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_MODULECODE, PREFIX_TUTORIALCLASS); + + if (!arePrefixesPresent(argMultimap, PREFIX_MODULECODE, PREFIX_TUTORIALCLASS) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteClassCommand.MESSAGE_USAGE)); + } + + String moduleCode = argMultimap.getValue(PREFIX_MODULECODE).orElse(""); + String tutorialClass = argMultimap.getValue(PREFIX_TUTORIALCLASS).orElse(""); + if (!(ModuleCode.isValidModuleCode(moduleCode))) { + throw new ParseException(ModuleCode.MESSAGE_CONSTRAINTS); + } + if (!(TutorialClass.isValidTutorialClass(tutorialClass))) { + throw new ParseException(TutorialClass.MESSAGE_CONSTRAINTS); + } + return new DeleteClassCommand(new ModuleCode(moduleCode), new TutorialClass(tutorialClass)); + } + + 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/model/module/ModuleCode.java b/src/main/java/seedu/address/model/module/ModuleCode.java index 7f14742f20c..a11752d05c5 100644 --- a/src/main/java/seedu/address/model/module/ModuleCode.java +++ b/src/main/java/seedu/address/model/module/ModuleCode.java @@ -1,5 +1,8 @@ package seedu.address.model.module; +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; + import static seedu.address.commons.util.AppUtil.checkArgument; import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; @@ -120,6 +123,24 @@ public boolean hasTutorialClass(TutorialClass tutorialString) { return false; } + /** + * List all the tutorial classes under this module. + * + * @return String of tutorial classes under this module. + */ + public String listTutorialClasses() { + if (tutorialClasses.size() == 0) { + return String.format("Tutorials in %s: None!", value); + } else { + StringBuilder tutorialsString = new StringBuilder(String.format("Tutorials in %s: ", value)); + for (TutorialClass tutorialClass : tutorialClasses) { + tutorialsString.append(" "); + tutorialsString.append(tutorialClass.toString()); + } + return tutorialsString.toString().trim(); + } + } + /** * Adds an empty tutorial with the given name into the module. * @@ -128,4 +149,14 @@ public boolean hasTutorialClass(TutorialClass tutorialString) { public void addTutorialClass(TutorialClass tutorialString) { tutorialClasses.add(tutorialString); } + + /** + * Deletes a tutorial with the given name from the module. + * The tutorial has to exist to be used in this function. + * + * @param tutorialString name of tutorial class to be deleted. + */ + public void deleteTutorialClass(TutorialClass tutorialString) { + tutorialClasses.remove(tutorialString); + } } diff --git a/src/test/java/seedu/address/logic/commands/AddClassCommandTest.java b/src/test/java/seedu/address/logic/commands/AddClassCommandTest.java index dab2203f195..ca2e5dac49f 100644 --- a/src/test/java/seedu/address/logic/commands/AddClassCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddClassCommandTest.java @@ -3,7 +3,7 @@ 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.AddClassCommand.MESSAGE_ADD_REMARK_SUCCESS; +import static seedu.address.logic.commands.AddClassCommand.MESSAGE_ADD_CLASS_SUCCESS; import static seedu.address.logic.commands.AddClassCommand.MESSAGE_DUPLICATE_CLASS; import static seedu.address.logic.commands.CommandTestUtil.VALID_MODULE_AMY; import static seedu.address.logic.commands.CommandTestUtil.VALID_MODULE_BOB; @@ -34,7 +34,7 @@ public void execute_success() { assertCommandSuccess(new AddClassCommand(new ModuleCode(VALID_MODULE_AMY), new TutorialClass(VALID_TUTORIAL_AMY)), model, - String.format(MESSAGE_ADD_REMARK_SUCCESS, VALID_MODULE_AMY, VALID_TUTORIAL_AMY), model); + String.format(MESSAGE_ADD_CLASS_SUCCESS, VALID_MODULE_AMY, VALID_TUTORIAL_AMY), model); } @Test @@ -64,7 +64,7 @@ public void execute_duplicateModuleDifferentTutorial_success() { assertCommandSuccess(new AddClassCommand(new ModuleCode(VALID_MODULE_AMY), new TutorialClass(VALID_TUTORIAL_BOB)), actualModel, - String.format(MESSAGE_ADD_REMARK_SUCCESS, VALID_MODULE_AMY, VALID_TUTORIAL_BOB), expectedModel); + String.format(MESSAGE_ADD_CLASS_SUCCESS, VALID_MODULE_AMY, VALID_TUTORIAL_BOB), expectedModel); ModuleCode moduleFromList = actualModel.findModuleFromList(module); assertEquals(moduleFromList.getTutorialClasses().get(1).toString(), VALID_TUTORIAL_BOB); diff --git a/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java new file mode 100644 index 00000000000..9ca5b46efc6 --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java @@ -0,0 +1,4 @@ +package seedu.address.logic.commands; + +public class DeleteClassCommandTest { +} diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index b60db684357..03fa512748f 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -19,6 +19,7 @@ import seedu.address.logic.commands.AddClassCommand; import seedu.address.logic.commands.AddCommand; import seedu.address.logic.commands.ClearCommand; +import seedu.address.logic.commands.DeleteClassCommand; import seedu.address.logic.commands.DeleteCommand; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; @@ -114,6 +115,17 @@ public void parseCommand_addClass() throws Exception { assertEquals(new AddClassCommand(new ModuleCode(moduleCode), new TutorialClass(tutorialClass)), command); } + + @Test + public void parseCommand_deleteClass() throws Exception { + final String moduleCode = "CS2103T"; + final String tutorialClass = "T09"; + AddClassCommand command = (AddClassCommand) parser.parseCommand(AddClassCommand.COMMAND_WORD + " " + + PREFIX_MODULECODE + moduleCode + " " + PREFIX_TUTORIALCLASS + tutorialClass); + assertEquals(new DeleteClassCommand(new ModuleCode(moduleCode), + new TutorialClass(tutorialClass)), command); + } + @Test public void parseCommand_listClasses() throws Exception { assertTrue(parser.parseCommand(ListClassesCommand.COMMAND_WORD) instanceof ListClassesCommand); diff --git a/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java new file mode 100644 index 00000000000..1e7fa275915 --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java @@ -0,0 +1,4 @@ +package seedu.address.logic.parser; + +public class DeleteClassCommandParserTest { +} From 95040e63f1b1a6c76ae567fd91b7362a0d0cad93 Mon Sep 17 00:00:00 2001 From: whelan-low Date: Mon, 18 Mar 2024 22:54:24 +0800 Subject: [PATCH 06/33] Fix checkstyle issues --- .../seedu/address/logic/commands/DeleteClassCommand.java | 8 +++++--- src/main/java/seedu/address/model/module/ModuleCode.java | 3 --- .../address/logic/commands/DeleteClassCommandTest.java | 9 +++++++++ .../logic/parser/DeleteClassCommandParserTest.java | 5 +++++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java b/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java index 8bb54c70c11..5ccf2bb93d5 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java @@ -2,7 +2,6 @@ import static java.util.Objects.requireNonNull; import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; -import static seedu.address.logic.commands.AddClassCommand.MESSAGE_ADD_CLASS_SUCCESS; import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULECODE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TUTORIALCLASS; @@ -11,13 +10,17 @@ import seedu.address.model.module.ModuleCode; import seedu.address.model.module.TutorialClass; +/** + * A class used to handle the deletion of tutorial classes. + */ public class DeleteClassCommand extends Command { public static final String MESSAGE_DELETE_CLASS_SUCCESS = "Removed %1$s %2$s!"; public static final String MESSAGE_MODULE_NOT_FOUND = "%1$s not in list!"; public static final String MESSAGE_CLASS_NOT_FOUND = "%1$s %2$s not in list!"; public static final String COMMAND_WORD = "/delete_class"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Deletes a class with the module code and tutorial class specified\n" + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Deletes a class with the module code and tutorial class specified\n" + "Parameters:" + PREFIX_MODULECODE + "MODULE_CODE (must be a String) " + PREFIX_TUTORIALCLASS + "TUTORIAL_CLASS (must be a String)" + "Example: " + COMMAND_WORD + PREFIX_MODULECODE + " CS2103T " @@ -41,7 +44,6 @@ public CommandResult execute(Model model) throws CommandException { ModuleCode existingModule = model.findModuleFromList(module); if (existingModule == null) { - new ListClassesCommand(); String moduleNotFoundMessage = String.format(MESSAGE_MODULE_NOT_FOUND, module); throw new CommandException(moduleNotFoundMessage); } diff --git a/src/main/java/seedu/address/model/module/ModuleCode.java b/src/main/java/seedu/address/model/module/ModuleCode.java index a11752d05c5..0c7eebcb1da 100644 --- a/src/main/java/seedu/address/model/module/ModuleCode.java +++ b/src/main/java/seedu/address/model/module/ModuleCode.java @@ -1,8 +1,5 @@ package seedu.address.model.module; -import seedu.address.logic.commands.Command; -import seedu.address.logic.commands.CommandResult; - import static seedu.address.commons.util.AppUtil.checkArgument; import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; diff --git a/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java index 9ca5b46efc6..c2a805f9a7e 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java @@ -1,4 +1,13 @@ package seedu.address.logic.commands; +import org.junit.jupiter.api.Test; + public class DeleteClassCommandTest { + @Test + void execute() { + } + + @Test + void testEquals() { + } } diff --git a/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java index 1e7fa275915..4bd7f697f0a 100644 --- a/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java @@ -1,4 +1,9 @@ package seedu.address.logic.parser; +import org.junit.jupiter.api.Test; + public class DeleteClassCommandParserTest { + @Test + void parse() { + } } From 3e62b5f309869c417f8df86639f9a3b4153ad880 Mon Sep 17 00:00:00 2001 From: whelan-low Date: Mon, 18 Mar 2024 23:17:04 +0800 Subject: [PATCH 07/33] Fix test case --- .../java/seedu/address/logic/parser/AddressBookParserTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 03fa512748f..9dd91030ac6 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -120,7 +120,8 @@ public void parseCommand_addClass() throws Exception { public void parseCommand_deleteClass() throws Exception { final String moduleCode = "CS2103T"; final String tutorialClass = "T09"; - AddClassCommand command = (AddClassCommand) parser.parseCommand(AddClassCommand.COMMAND_WORD + " " + DeleteClassCommand command = (DeleteClassCommand) + parser.parseCommand(DeleteClassCommand.COMMAND_WORD + " " + PREFIX_MODULECODE + moduleCode + " " + PREFIX_TUTORIALCLASS + tutorialClass); assertEquals(new DeleteClassCommand(new ModuleCode(moduleCode), new TutorialClass(tutorialClass)), command); From 94390c1e08530b41cbe103f995f7ba57926f2b86 Mon Sep 17 00:00:00 2001 From: whelan-low Date: Tue, 19 Mar 2024 00:41:14 +0800 Subject: [PATCH 08/33] Add test cases --- .../address/model/module/ModuleCode.java | 2 +- .../commands/DeleteClassCommandTest.java | 88 ++++++++++++++++++- .../parser/DeleteClassCommandParserTest.java | 45 +++++++++- .../address/model/module/ModuleCodeTest.java | 41 ++++++++- 4 files changed, 170 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/address/model/module/ModuleCode.java b/src/main/java/seedu/address/model/module/ModuleCode.java index 0c7eebcb1da..58b13d16fdc 100644 --- a/src/main/java/seedu/address/model/module/ModuleCode.java +++ b/src/main/java/seedu/address/model/module/ModuleCode.java @@ -129,7 +129,7 @@ public String listTutorialClasses() { if (tutorialClasses.size() == 0) { return String.format("Tutorials in %s: None!", value); } else { - StringBuilder tutorialsString = new StringBuilder(String.format("Tutorials in %s: ", value)); + StringBuilder tutorialsString = new StringBuilder(String.format("Tutorials in %s:", value)); for (TutorialClass tutorialClass : tutorialClasses) { tutorialsString.append(" "); tutorialsString.append(tutorialClass.toString()); diff --git a/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java index c2a805f9a7e..930a7714e7d 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java @@ -1,13 +1,97 @@ 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_MODULE_AMY; +import static seedu.address.logic.commands.CommandTestUtil.VALID_MODULE_BOB; +import static seedu.address.logic.commands.CommandTestUtil.VALID_TUTORIAL_AMY; +import static seedu.address.logic.commands.CommandTestUtil.VALID_TUTORIAL_BOB; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.address.logic.commands.DeleteClassCommand.MESSAGE_CLASS_NOT_FOUND; +import static seedu.address.logic.commands.DeleteClassCommand.MESSAGE_DELETE_CLASS_SUCCESS; +import static seedu.address.logic.commands.DeleteClassCommand.MESSAGE_MODULE_NOT_FOUND; +import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; + import org.junit.jupiter.api.Test; +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; + +/** + * Contains integration tests (interaction with the Model) and unit tests for AddClassCommand. + */ public class DeleteClassCommandTest { + private final Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + + @Test + public void execute_success() { + Model actualModel = new ModelManager(); + Model expectedModel = new ModelManager(); + ModuleCode module = new ModuleCode(VALID_MODULE_AMY, VALID_TUTORIAL_AMY); + actualModel.addModule(module); + expectedModel.addModule(new ModuleCode(VALID_MODULE_AMY)); + + assertCommandSuccess(new DeleteClassCommand(new ModuleCode(VALID_MODULE_AMY), + new TutorialClass(VALID_TUTORIAL_AMY)), actualModel, + String.format(MESSAGE_DELETE_CLASS_SUCCESS, VALID_MODULE_AMY, VALID_TUTORIAL_AMY), expectedModel); + + ModuleCode moduleFromList = actualModel.findModuleFromList(module); + assertEquals(moduleFromList.getTutorialClasses().size(), 0); + } + + @Test + public void execute_moduleNotFound_fail() { + ModuleCode module = new ModuleCode(VALID_MODULE_AMY, VALID_TUTORIAL_AMY); + model.addModule(module); + + assertCommandFailure(new DeleteClassCommand(new ModuleCode(VALID_MODULE_BOB), + new TutorialClass(VALID_TUTORIAL_AMY)), model, + String.format(MESSAGE_MODULE_NOT_FOUND, VALID_MODULE_BOB)); + } + @Test - void execute() { + public void execute_tutorialNotFound_fail() { + ModuleCode module = new ModuleCode(VALID_MODULE_AMY, VALID_TUTORIAL_AMY); + model.addModule(module); + + String errorMessage = String.format(MESSAGE_CLASS_NOT_FOUND, VALID_MODULE_AMY, VALID_TUTORIAL_BOB); + String listOfTutorials = module.listTutorialClasses(); + String expectedMessage = errorMessage + "\n" + listOfTutorials; + assertCommandFailure(new DeleteClassCommand(new ModuleCode(VALID_MODULE_AMY), + new TutorialClass(VALID_TUTORIAL_BOB)), model, expectedMessage); } @Test - void testEquals() { + public void equals() { + final DeleteClassCommand standardCommand = new DeleteClassCommand(new ModuleCode(VALID_MODULE_AMY), + new TutorialClass(VALID_TUTORIAL_AMY)); + + // same values -> returns true + DeleteClassCommand commandWithSameValues = new DeleteClassCommand(new ModuleCode(VALID_MODULE_AMY), + new TutorialClass(VALID_TUTORIAL_AMY)); + assertTrue(standardCommand.equals(commandWithSameValues)); + + // same object -> returns true + assertTrue(standardCommand.equals(standardCommand)); + + // null -> returns false + assertFalse(standardCommand.equals(null)); + + // different types -> returns false + assertFalse(standardCommand.equals(new ClearCommand())); + + // different module code -> returns false + assertFalse(standardCommand.equals(new DeleteClassCommand(new ModuleCode(VALID_MODULE_BOB), + new TutorialClass(VALID_TUTORIAL_AMY)))); + + // different tutorial class -> returns true + assertTrue(standardCommand.equals(new DeleteClassCommand(new ModuleCode(VALID_MODULE_AMY), + new TutorialClass(VALID_TUTORIAL_BOB)))); } } + diff --git a/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java index 4bd7f697f0a..6db8ed91245 100644 --- a/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java @@ -1,9 +1,52 @@ package seedu.address.logic.parser; +import static seedu.address.logic.commands.CommandTestUtil.MODULE_DESC_AMY; +import static seedu.address.logic.commands.CommandTestUtil.TUTORIAL_DESC_AMY; +import static seedu.address.logic.commands.CommandTestUtil.VALID_MODULE_AMY; +import static seedu.address.logic.commands.CommandTestUtil.VALID_TUTORIAL_AMY; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULECODE; +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 org.junit.jupiter.api.Test; +import seedu.address.logic.Messages; +import seedu.address.logic.commands.DeleteClassCommand; +import seedu.address.model.module.ModuleCode; +import seedu.address.model.module.TutorialClass; + public class DeleteClassCommandParserTest { + private final DeleteClassCommandParser parser = new DeleteClassCommandParser(); + + + @Test + public void parse_tutorialTest() { + // have tutorial class + String expectedMessage = TutorialClass.MESSAGE_CONSTRAINTS; + + String userInput = MODULE_DESC_AMY + TUTORIAL_DESC_AMY; + DeleteClassCommand expectedCommand = new DeleteClassCommand(new ModuleCode(VALID_MODULE_AMY), + new TutorialClass(VALID_TUTORIAL_AMY)); + assertParseSuccess(parser, userInput, expectedCommand); + + // no tutorial class + userInput = MODULE_DESC_AMY + " " + PREFIX_TUTORIALCLASS; + assertParseFailure(parser, userInput, expectedMessage); + } + @Test - void parse() { + public void parse_missingCompulsoryField_failure() { + String expectedMessage1 = String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, + DeleteClassCommand.MESSAGE_USAGE); + String expectedMessage2 = ModuleCode.MESSAGE_CONSTRAINTS; + + // no parameters + assertParseFailure(parser, " ", expectedMessage1); + + // no module stated + assertParseFailure(parser, " " + PREFIX_MODULECODE + "" + + TUTORIAL_DESC_AMY, expectedMessage2); } } + diff --git a/src/test/java/seedu/address/model/module/ModuleCodeTest.java b/src/test/java/seedu/address/model/module/ModuleCodeTest.java index 8009ae0983c..22f7cb69c64 100644 --- a/src/test/java/seedu/address/model/module/ModuleCodeTest.java +++ b/src/test/java/seedu/address/model/module/ModuleCodeTest.java @@ -11,6 +11,12 @@ public class ModuleCodeTest { public static final String VALID_MODULE_CODE = "CS2103T"; public static final String INVALID_MODULE_CODE = "CS210T"; + public static final String VALID_TUTORIAL_1 = "T01"; + public static final String VALID_TUTORIAL_2 = "T02"; + + /** + * Test cases to check the equality of two ModuleCode objects + */ @Test public void equals() { ModuleCode module = new ModuleCode("CS2103T"); @@ -32,20 +38,51 @@ public void equals() { ModuleCode differentModule = new ModuleCode("CS1101S"); assertFalse(module.equals(differentModule)); } + + /** + * Tests isValidModuleCode with a valid module code. + */ @Test - void isValidTutorialClass_success() { + void isValidModuleCode_success() { assertTrue(isValidModuleCode(VALID_MODULE_CODE)); } + /** + * Tests isValidModuleCode with an invalid module code + */ @Test - void isValidTutorialClass_failure() { + void isValidModuleCode_failure() { assertFalse(isValidModuleCode(INVALID_MODULE_CODE)); } + /** + * Checks if the string output is as expected for a valid module. + */ @Test void testToString_success() { ModuleCode moduleCode = new ModuleCode(VALID_MODULE_CODE); assertEquals(moduleCode.toString(), VALID_MODULE_CODE); } + /** + * Checks if the string output is as expected for a set list of tutorial classes. + */ + @Test + void listTutorialClasses_success() { + ModuleCode moduleCode = new ModuleCode(VALID_MODULE_CODE); + moduleCode.addTutorialClass(new TutorialClass(VALID_TUTORIAL_1)); + moduleCode.addTutorialClass(new TutorialClass(VALID_TUTORIAL_2)); + String expectedString = "Tutorials in CS2103T: T01 T02"; + assertEquals(moduleCode.listTutorialClasses(), expectedString); + } + + /** + * Checks if the string output is as expected for an empty module. + */ + @Test + void listTutorialClasses_empty_success() { + ModuleCode moduleCode = new ModuleCode(VALID_MODULE_CODE); + String expectedString = "Tutorials in CS2103T: None!"; + assertEquals(moduleCode.listTutorialClasses(), expectedString); + } } From be4156750b0e06e2109a722f36bfb217e62092c1 Mon Sep 17 00:00:00 2001 From: whelan-low Date: Tue, 19 Mar 2024 15:04:18 +0800 Subject: [PATCH 09/33] Fix merge conflict --- .../seedu/address/model/module/ModuleCode.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/main/java/seedu/address/model/module/ModuleCode.java b/src/main/java/seedu/address/model/module/ModuleCode.java index 7b6f302bc66..3506db8a8de 100644 --- a/src/main/java/seedu/address/model/module/ModuleCode.java +++ b/src/main/java/seedu/address/model/module/ModuleCode.java @@ -135,15 +135,9 @@ public boolean hasTutorialClass(TutorialClass tutorialClass) { */ public String listTutorialClasses() { if (tutorialClasses.size() == 0) { -<<<<<<< HEAD - return String.format("Tutorials in %s: None!", value); - } else { - StringBuilder tutorialsString = new StringBuilder(String.format("Tutorials in %s:", value)); -======= return String.format("Tutorials in %s: None!", moduleCode); } else { StringBuilder tutorialsString = new StringBuilder(String.format("Tutorials in %s:", moduleCode)); ->>>>>>> origin/master for (TutorialClass tutorialClass : tutorialClasses) { tutorialsString.append(" "); tutorialsString.append(tutorialClass.toString()); @@ -170,14 +164,4 @@ public void addTutorialClass(TutorialClass tutorialClass) { public void deleteTutorialClass(TutorialClass tutorialClass) { tutorialClasses.remove(tutorialClass); } - - /** - * Deletes a tutorial with the given name from the module. - * The tutorial has to exist to be used in this function. - * - * @param tutorialString name of tutorial class to be deleted. - */ - public void deleteTutorialClass(TutorialClass tutorialString) { - tutorialClasses.remove(tutorialString); - } } From 8a63f0b44d25e0a574c9e3a381aad5a416181f56 Mon Sep 17 00:00:00 2001 From: Jajared Date: Tue, 19 Mar 2024 15:05:29 +0800 Subject: [PATCH 10/33] Added integration tests --- .../AddStudentToClassCommand.java | 3 +- .../logic/messages/ModuleMessages.java | 2 + ...dStudentToClassCommandIntegrationTest.java | 13 +++++ .../AddStudentToClassCommandTest.java | 3 +- .../logic/parser/AddressBookParserTest.java | 47 ++++++++++++++++--- 5 files changed, 57 insertions(+), 11 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java index 709e105350f..7cfa24df072 100644 --- a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java @@ -10,7 +10,6 @@ import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.logic.messages.ModuleMessages; -import seedu.address.logic.messages.TutorialClassMessages; import seedu.address.model.Model; import seedu.address.model.module.ModuleCode; import seedu.address.model.module.ModuleTutorialPair; @@ -50,7 +49,7 @@ protected ModuleTutorialPair getModuleAndTutorialClass(Model model) throws Comma } if (!existingModule.hasTutorialClass(tutorialClass)) { throw new CommandException( - String.format(TutorialClassMessages.MESSAGE_TUTORIAL_CLASS_NOT_FOUND, tutorialClass)); + String.format(ModuleMessages.MESSAGE_TUTORIAL_DOES_NOT_BELONG_TO_MODULE, tutorialClass, module)); } return new ModuleTutorialPair(module, tutorialClass); } diff --git a/src/main/java/seedu/address/logic/messages/ModuleMessages.java b/src/main/java/seedu/address/logic/messages/ModuleMessages.java index 5aa0d3bbc04..c73bf1ec2f1 100644 --- a/src/main/java/seedu/address/logic/messages/ModuleMessages.java +++ b/src/main/java/seedu/address/logic/messages/ModuleMessages.java @@ -6,4 +6,6 @@ public class ModuleMessages { public static final String MESSAGE_MODULE_NOT_FOUND = "The module with module code %s " + "does not exist in the address book"; + public static final String MESSAGE_TUTORIAL_DOES_NOT_BELONG_TO_MODULE = "The tutorial class with tutorial code %s " + + "does not belong to the module with module code %s"; } diff --git a/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandIntegrationTest.java index 871f40adbe6..6ad3bc2d907 100644 --- a/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandIntegrationTest.java +++ b/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandIntegrationTest.java @@ -91,4 +91,17 @@ public void execute_addStudentToInvalidClass_throwsCommandException() { expectedModel, String.format(ModuleMessages.MESSAGE_MODULE_NOT_FOUND, newModule)); } + @Test + public void execute_addStudentToValidModuleButInvalidTutorial_throwsCommandException() { + Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + + ModuleCode newModule = new ModuleCode(VALID_MODULE_AMY); + expectedModel.addModule(newModule); + TutorialClass newTutorial = new TutorialClass(VALID_TUTORIAL_BOB); + Person validPerson = new PersonBuilder().build(); + assertCommandFailure(new AddStudentToClassByEmailCommand(validPerson.getEmail(), newModule, newTutorial), + expectedModel, + String.format(ModuleMessages.MESSAGE_TUTORIAL_DOES_NOT_BELONG_TO_MODULE, newTutorial, newModule)); + } + } diff --git a/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java b/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java index 661da36824d..17a474f0c25 100644 --- a/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java @@ -39,7 +39,6 @@ public class AddStudentToClassCommandTest { private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); - private TutorialClass tutorialClass; @BeforeEach public void setUp() { @@ -47,7 +46,6 @@ public void setUp() { model.addModule(newModule); TutorialClass newTutorialClass = new TutorialClass(VALID_TUTORIAL_AMY); newModule.addTutorialClass(newTutorialClass); - tutorialClass = newTutorialClass; } @Test @@ -64,6 +62,7 @@ public void execute_invalidStudent_fail() { String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, INVALID_STUDENT_ID)); } + /* @Test public void execute_duplicateStudent_fail() { Person person = new PersonBuilder().build(); diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 9dd91030ac6..4d5d7caeaab 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -4,8 +4,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; import static seedu.address.logic.Messages.MESSAGE_UNKNOWN_COMMAND; +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.parser.CliSyntax.PREFIX_EMAIL; import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULECODE; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_STUDENTID; import static seedu.address.logic.parser.CliSyntax.PREFIX_TUTORIALCLASS; import static seedu.address.testutil.Assert.assertThrows; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; @@ -16,6 +20,7 @@ import org.junit.jupiter.api.Test; +import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.AddClassCommand; import seedu.address.logic.commands.AddCommand; import seedu.address.logic.commands.ClearCommand; @@ -29,12 +34,17 @@ import seedu.address.logic.commands.ListClassesCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.SearchStudentCommand; +import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByEmailCommand; +import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByIdCommand; +import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassCommand; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.module.ModuleCode; import seedu.address.model.module.TutorialClass; +import seedu.address.model.person.Email; import seedu.address.model.person.NameContainsKeywordPredicate; import seedu.address.model.person.NameContainsKeywordsPredicate; import seedu.address.model.person.Person; +import seedu.address.model.person.StudentId; import seedu.address.testutil.EditPersonDescriptorBuilder; import seedu.address.testutil.PersonBuilder; import seedu.address.testutil.PersonUtil; @@ -59,7 +69,7 @@ public void parseCommand_clear() throws Exception { @Test public void parseCommand_delete() throws Exception { DeleteCommand command = (DeleteCommand) parser.parseCommand( - DeleteCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased()); + DeleteCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased()); assertEquals(new DeleteCommand(INDEX_FIRST_PERSON), command); } @@ -68,7 +78,7 @@ public void parseCommand_edit() throws Exception { Person person = new PersonBuilder().build(); EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(person).build(); EditCommand command = (EditCommand) parser.parseCommand(EditCommand.COMMAND_WORD + " " - + INDEX_FIRST_PERSON.getOneBased() + " " + PersonUtil.getEditPersonDescriptorDetails(descriptor)); + + INDEX_FIRST_PERSON.getOneBased() + " " + PersonUtil.getEditPersonDescriptorDetails(descriptor)); assertEquals(new EditCommand(INDEX_FIRST_PERSON, descriptor), command); } @@ -82,7 +92,7 @@ public void parseCommand_exit() throws Exception { public void parseCommand_find() throws Exception { List keywords = Arrays.asList("foo", "bar", "baz"); FindCommand command = (FindCommand) parser.parseCommand( - FindCommand.COMMAND_WORD + " " + keywords.stream().collect(Collectors.joining(" "))); + FindCommand.COMMAND_WORD + " " + keywords.stream().collect(Collectors.joining(" "))); assertEquals(new FindCommand(new NameContainsKeywordsPredicate(keywords)), command); } @@ -120,8 +130,7 @@ public void parseCommand_addClass() throws Exception { public void parseCommand_deleteClass() throws Exception { final String moduleCode = "CS2103T"; final String tutorialClass = "T09"; - DeleteClassCommand command = (DeleteClassCommand) - parser.parseCommand(DeleteClassCommand.COMMAND_WORD + " " + DeleteClassCommand command = (DeleteClassCommand) parser.parseCommand(DeleteClassCommand.COMMAND_WORD + " " + PREFIX_MODULECODE + moduleCode + " " + PREFIX_TUTORIALCLASS + tutorialClass); assertEquals(new DeleteClassCommand(new ModuleCode(moduleCode), new TutorialClass(tutorialClass)), command); @@ -132,10 +141,34 @@ public void parseCommand_listClasses() throws Exception { assertTrue(parser.parseCommand(ListClassesCommand.COMMAND_WORD) instanceof ListClassesCommand); assertTrue(parser.parseCommand(ListClassesCommand.COMMAND_WORD + " 3") instanceof ListClassesCommand); } + + @Test + public void parseCommand_addStudentToClass() throws Exception { + final String moduleCode = "CS2103T"; + final String tutorialClass = "T09"; + final String email = VALID_EMAIL_AMY; + final String id = VALID_STUDENT_ID_AMY; + final Index index = INDEX_FIRST_PERSON; + AddStudentToClassCommand addByEmailCommand = (AddStudentToClassCommand) parser.parseCommand( + AddStudentToClassCommand.COMMAND_WORD + " " + PREFIX_EMAIL + email + " " + PREFIX_MODULECODE + + moduleCode + " " + + PREFIX_TUTORIALCLASS + tutorialClass); + AddStudentToClassCommand addByIdCommand = (AddStudentToClassCommand) parser.parseCommand( + AddStudentToClassCommand.COMMAND_WORD + " " + PREFIX_STUDENTID + id + " " + PREFIX_MODULECODE + + moduleCode + " " + + PREFIX_TUTORIALCLASS + tutorialClass); + assertEquals(new AddStudentToClassByEmailCommand(new Email(VALID_EMAIL_AMY), new ModuleCode(moduleCode), + new TutorialClass(tutorialClass)), addByEmailCommand); + assertEquals(new AddStudentToClassByIdCommand(new StudentId(VALID_STUDENT_ID_AMY), new ModuleCode(moduleCode), + new TutorialClass(tutorialClass)), addByIdCommand); + + } + @Test public void parseCommand_unrecognisedInput_throwsParseException() { - assertThrows(ParseException.class, String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE), () - -> parser.parseCommand("")); + assertThrows(ParseException.class, + String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE), ( + ) -> parser.parseCommand("")); } @Test From 55ed508d58d652ec8be71f934ae5d2a6e5a24607 Mon Sep 17 00:00:00 2001 From: Jajared Date: Tue, 19 Mar 2024 15:25:09 +0800 Subject: [PATCH 11/33] Add more test cases for delete student --- .../DeleteStudentCommandIntegrationTest.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/test/java/seedu/address/logic/commands/DeleteStudentCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/DeleteStudentCommandIntegrationTest.java index 6bdca87b950..d79bfb54555 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteStudentCommandIntegrationTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteStudentCommandIntegrationTest.java @@ -2,19 +2,23 @@ import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; 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.Messages; import seedu.address.logic.commands.deletestudentcommands.DeleteStudentByEmailCommand; import seedu.address.logic.commands.deletestudentcommands.DeleteStudentByIdCommand; +import seedu.address.logic.commands.deletestudentcommands.DeleteStudentByIndexCommand; import seedu.address.logic.commands.deletestudentcommands.DeleteStudentCommand; import seedu.address.logic.messages.PersonMessages; import seedu.address.model.Model; import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; +import seedu.address.model.person.Email; import seedu.address.model.person.Person; import seedu.address.model.person.StudentId; import seedu.address.testutil.PersonBuilder; @@ -46,6 +50,19 @@ public void execute_deleteStudentById_success() { expectedModel); } + @Test + public void execute_deleteStudentbyIndex_success() { + Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + + // Get first student from the list + Person person = expectedModel.getFilteredPersonList().get(0); + + // Attempt to delete the student + assertCommandSuccess(new DeleteStudentByIndexCommand(INDEX_FIRST_PERSON), expectedModel, + String.format(DeleteStudentCommand.MESSAGE_DELETE_PERSON_SUCCESS, Messages.format(person)), + expectedModel); + } + @Test public void execute_deleteStudentByEmail_success() { Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); @@ -75,4 +92,26 @@ public void execute_deleteStudentWithInvalidId_throwsCommandException() { String.format(PersonMessages.MESSAGE_PERSON_STUDENT_ID_NOT_FOUND, "A0123456X")); } + @Test + public void execute_deleteStudentWithInvalidEmail_throwsCommandException() { + Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + + Email invalidEmail = new Email("invalidEmail@example.com"); + + // Attempt to delete the student + assertCommandFailure(new DeleteStudentByEmailCommand(invalidEmail), expectedModel, + String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, "invalidEmail@example.com")); + } + + @Test + public void execute_deleteStudentwithInvalidIndex_throwsCommandException() { + Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + + Index invalidIndex = Index.fromOneBased(1000); + + // Attempt to delete the student + assertCommandFailure(new DeleteStudentByIndexCommand(invalidIndex), expectedModel, + String.format(PersonMessages.MESSAGE_PERSON_INDEX_NOT_FOUND, 1000)); + } + } From 49e64fd676a77f8783594e6a3325961e556be89f Mon Sep 17 00:00:00 2001 From: qinxutan Date: Tue, 19 Mar 2024 21:49:27 +0800 Subject: [PATCH 12/33] Update Javadocs --- .../seedu/address/logic/commands/AddClassCommand.java | 10 +++++++--- .../address/logic/commands/DeleteClassCommand.java | 10 +++++++--- .../address/logic/parser/AddClassCommandParser.java | 4 +++- .../address/logic/parser/DeleteClassCommandParser.java | 4 +++- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/AddClassCommand.java b/src/main/java/seedu/address/logic/commands/AddClassCommand.java index cfcfa92c930..2016f317663 100644 --- a/src/main/java/seedu/address/logic/commands/AddClassCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddClassCommand.java @@ -28,7 +28,9 @@ public class AddClassCommand extends Command { private final TutorialClass tutorialString; /** - * @param module of the tutorial class to be added + * Constructs an AddClassCommand to add the specified {@code TutorialClass} to the specified {@code ModuleCode}. + * @param module The module code of the tutorial class to be added. + * @param tutorialClass The tutorial class to be added. */ public AddClassCommand(ModuleCode module, TutorialClass tutorialClass) { requireAllNonNull(module); @@ -56,8 +58,10 @@ public CommandResult execute(Model model) throws CommandException { } /** - * Generates a command execution success message based on whether the remark is added to or removed from - * {@code personToEdit}. + * Generates a command execution success message based on whether the tutorial class is added successfully. + * @param module The module code of the tutorial class. + * @param tutorialString The tutorial class. + * @return The success message. */ private String generateSuccessMessage(ModuleCode module, TutorialClass tutorialString) { return String.format(MESSAGE_ADD_CLASS_SUCCESS, module.toString(), tutorialString.toString()); diff --git a/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java b/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java index 5ccf2bb93d5..c273b1b63aa 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java @@ -30,7 +30,9 @@ public class DeleteClassCommand extends Command { private final TutorialClass tutorialString; /** - * @param module of the tutorial class to be added + * Constructs a DeleteClassCommand to delete the specified {@code TutorialClass} from the specified {@code ModuleCode}. + * @param module The module code of the tutorial class to be deleted. + * @param tutorialClass The tutorial class to be deleted. */ public DeleteClassCommand(ModuleCode module, TutorialClass tutorialClass) { requireAllNonNull(module); @@ -60,8 +62,10 @@ public CommandResult execute(Model model) throws CommandException { } /** - * Generates a command execution success message based on whether the removed from - * {@code personToEdit}. + * Generates a command execution success message based on whether the tutorial class is successfully deleted. + * @param module The module code of the tutorial class. + * @param tutorialString The tutorial class. + * @return The success message. */ private String generateSuccessMessage(ModuleCode module, TutorialClass tutorialString) { return String.format(MESSAGE_DELETE_CLASS_SUCCESS, module.toString(), tutorialString.toString()); diff --git a/src/main/java/seedu/address/logic/parser/AddClassCommandParser.java b/src/main/java/seedu/address/logic/parser/AddClassCommandParser.java index 91db403f30a..cc2262b06f9 100644 --- a/src/main/java/seedu/address/logic/parser/AddClassCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddClassCommandParser.java @@ -42,7 +42,9 @@ public AddClassCommand parse(String args) throws ParseException { } return new AddClassCommand(new ModuleCode(moduleCode), new TutorialClass(tutorialClass)); } - + /** + * Returns true if all the prefixes are present 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/DeleteClassCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteClassCommandParser.java index 75cafed54e7..fe761612a3f 100644 --- a/src/main/java/seedu/address/logic/parser/DeleteClassCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/DeleteClassCommandParser.java @@ -42,7 +42,9 @@ public DeleteClassCommand parse(String args) throws ParseException { } return new DeleteClassCommand(new ModuleCode(moduleCode), new TutorialClass(tutorialClass)); } - + /** + * Returns true if all the prefixes are present in the given {@code ArgumentMultimap}. + */ private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); } From c7a1f5b69441538efef805e8ee5443580083379f Mon Sep 17 00:00:00 2001 From: qinxutan Date: Tue, 19 Mar 2024 22:38:39 +0800 Subject: [PATCH 13/33] Update Javadocs --- src/main/java/seedu/address/logic/Logic.java | 3 +++ .../logic/commands/DeleteClassCommand.java | 3 ++- .../java/seedu/address/model/AddressBook.java | 3 +++ src/main/java/seedu/address/model/Model.java | 11 +++++++++++ .../java/seedu/address/model/ModelManager.java | 5 ++++- .../address/model/ReadOnlyAddressBook.java | 17 +++++++++++++++++ .../module/ModuleContainsKeywordPredicate.java | 5 ++++- .../address/model/module/TutorialClass.java | 10 ++++++++++ .../TutorialContainsKeywordPredicate.java | 5 ++++- .../person/EmailContainsKeywordPredicate.java | 4 ++++ .../person/NameContainsKeywordPredicate.java | 4 ++++ .../StudentIdContainsKeywordPredicate.java | 5 +++++ .../storage/JsonSerializableAddressBook.java | 2 +- src/main/java/seedu/address/ui/MainWindow.java | 18 ++++++++++++++++++ .../java/seedu/address/AppParametersTest.java | 7 +++++++ .../seedu/address/logic/LogicManagerTest.java | 3 +++ .../logic/commands/AddClassCommandTest.java | 3 ++- .../address/logic/commands/AddCommandTest.java | 4 ++++ .../logic/commands/ClearCommandTest.java | 4 ++++ .../logic/commands/CommandResultTest.java | 4 ++++ .../logic/commands/DeleteClassCommandTest.java | 3 ++- .../DeleteStudentCommandIntegrationTest.java | 2 +- .../commands/EditPersonDescriptorTest.java | 4 ++++ .../logic/commands/ExitCommandTest.java | 4 ++++ .../logic/commands/HelpCommandTest.java | 4 ++++ .../logic/commands/ListClassesCommandTest.java | 4 ++++ .../logic/commands/ListCommandTest.java | 3 ++- .../parser/AddClassCommandParserTest.java | 3 +++ .../logic/parser/AddCommandParserTest.java | 3 +++ .../logic/parser/AddressBookParserTest.java | 3 +++ .../logic/parser/ArgumentTokenizerTest.java | 3 +++ .../parser/DeleteClassCommandParserTest.java | 7 +++++++ .../parser/DeleteStudentCommandParserTest.java | 4 ++-- .../logic/parser/EditCommandParserTest.java | 3 +++ .../logic/parser/FindCommandParserTest.java | 3 +++ .../address/logic/parser/ParserUtilTest.java | 3 +++ .../parser/SearchStudentCommandParserTest.java | 3 +++ .../seedu/address/model/AddressBookTest.java | 3 +++ .../seedu/address/model/ModelManagerTest.java | 3 +++ .../seedu/address/model/UserPrefsTest.java | 3 +++ .../address/model/module/ModuleCodeTest.java | 3 +++ .../ModuleContainsKeywordPredicateTest.java | 3 +++ .../model/module/TutorialClassTest.java | 3 +++ .../TutorialContainsKeywordPredicateTest.java | 3 +++ .../address/model/person/AddressTest.java | 3 +++ .../EmailContainsKeywordPredicateTest.java | 3 +++ .../seedu/address/model/person/EmailTest.java | 3 +++ .../NameContainsKeywordPredicateTest.java | 3 +++ .../NameContainsKeywordsPredicateTest.java | 3 +++ .../seedu/address/model/person/NameTest.java | 3 +++ .../seedu/address/model/person/PersonTest.java | 3 +++ .../seedu/address/model/person/PhoneTest.java | 3 +++ .../StudentIdContainsKeywordPredicateTest.java | 3 +++ .../model/person/UniquePersonListTest.java | 3 +++ .../seedu/address/testutil/TypicalModules.java | 5 +++++ .../seedu/address/testutil/TypicalPersons.java | 5 +++++ .../seedu/address/ui/JavaFxInitializer.java | 15 --------------- src/test/java/seedu/address/ui/UiPartTest.java | 3 +++ 58 files changed, 232 insertions(+), 26 deletions(-) delete mode 100644 src/test/java/seedu/address/ui/JavaFxInitializer.java diff --git a/src/main/java/seedu/address/logic/Logic.java b/src/main/java/seedu/address/logic/Logic.java index 321aee8712c..972f2edb240 100644 --- a/src/main/java/seedu/address/logic/Logic.java +++ b/src/main/java/seedu/address/logic/Logic.java @@ -46,5 +46,8 @@ public interface Logic { * Set the user prefs' GUI settings. */ void setGuiSettings(GuiSettings guiSettings); + /** + * Checks if the initial module list panel is displayed. + */ boolean isInitialModuleListPanelDisplayed(); } diff --git a/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java b/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java index c273b1b63aa..a35dd291455 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteClassCommand.java @@ -30,7 +30,8 @@ public class DeleteClassCommand extends Command { private final TutorialClass tutorialString; /** - * Constructs a DeleteClassCommand to delete the specified {@code TutorialClass} from the specified {@code ModuleCode}. + * Constructs a DeleteClassCommand to delete the specified {@code TutorialClass} + * from the specified {@code ModuleCode}. * @param module The module code of the tutorial class to be deleted. * @param tutorialClass The tutorial class to be deleted. */ diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index dd520856e22..4adc334b273 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -53,6 +53,9 @@ public void setPersons(List persons) { this.persons.setPersons(persons); } + /** + * Replaces the contents of the module list with {@code modules}. + */ public void setModules(List modules) { requireNonNull(modules); this.modules.clear(); diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index 4e023b3e8f3..04c36e0c67b 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -94,13 +94,24 @@ public interface Model { /** Returns an unmodifiable view of the filtered person list */ ObservableList getFilteredPersonList(); + /** Returns an unmodifiable view of the filtered module list */ ObservableList getFilteredModuleList(); /** * Updates the filter of the filtered person list to filter by the given {@code predicate}. + * + * @param predicate The predicate used to filter the person list. * @throws NullPointerException if {@code predicate} is null. */ void updateFilteredPersonList(Predicate predicate); + + /** + * Updates the filter of the filtered module list to filter by the given {@code predicate}. + * + * @param predicate The predicate used to filter the module list. + * @throws NullPointerException if {@code predicate} is null. + */ + void updateFilteredModuleList(Predicate predicate); /** * Search for person by a given {@code predicate}. diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index abc0bc8823e..3678c7e0ee0 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -134,7 +134,10 @@ public void setPerson(Person target, Person editedPerson) { public ObservableList getFilteredPersonList() { return filteredPersons; } - + /** + * Returns an unmodifiable view of the list of {@code Module} backed by the internal list of + * {@code versionedAddressBook} + */ @Override public ObservableList getFilteredModuleList() { return filteredModules; diff --git a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java index 1b7eb6e50cb..d3463ca7cbc 100644 --- a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java +++ b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java @@ -15,7 +15,24 @@ public interface ReadOnlyAddressBook { */ ObservableList getPersonList(); + /** + * Returns an unmodifiable view of the modules list. + * This list will not contain any duplicate modules. + */ ObservableList getModuleList(); + + /** + * Checks if the address book contains the specified module code. + * + * @param moduleCode The module code to check. + * @return {@code true} if the address book contains the specified module code, {@code false} otherwise. + */ boolean hasModule(ModuleCode moduleCode); + + /** + * Adds a module code to the address book. + * + * @param moduleCode The module code to add. + */ void addModule(ModuleCode moduleCode); } diff --git a/src/main/java/seedu/address/model/module/ModuleContainsKeywordPredicate.java b/src/main/java/seedu/address/model/module/ModuleContainsKeywordPredicate.java index d158305f9a1..19ee616970a 100644 --- a/src/main/java/seedu/address/model/module/ModuleContainsKeywordPredicate.java +++ b/src/main/java/seedu/address/model/module/ModuleContainsKeywordPredicate.java @@ -11,7 +11,10 @@ public class ModuleContainsKeywordPredicate implements Predicate { private final String keyword; - + /** + * Constructs a ModuleContainsKeywordPredicate with the specified keyword. + * @param keyword The keyword to search for in module codes. + */ public ModuleContainsKeywordPredicate(String keyword) { this.keyword = keyword; } diff --git a/src/main/java/seedu/address/model/module/TutorialClass.java b/src/main/java/seedu/address/model/module/TutorialClass.java index 2598f4386a7..b07fa68a383 100644 --- a/src/main/java/seedu/address/model/module/TutorialClass.java +++ b/src/main/java/seedu/address/model/module/TutorialClass.java @@ -64,9 +64,19 @@ public TutorialClass(String tutorialClass, ArrayList students) { public static boolean isValidTutorialClass(String test) { return test.matches(VALIDATION_REGEX); } + /** + * Retrieves the tutorial class. + * + * @return The tutorial class. + */ public TutorialClass getTutorialClass() { return this; } + /** + * Retrieves the list of students in the tutorial class. + * + * @return The list of students in the tutorial class. + */ public ArrayList getStudents() { return this.students; } diff --git a/src/main/java/seedu/address/model/module/TutorialContainsKeywordPredicate.java b/src/main/java/seedu/address/model/module/TutorialContainsKeywordPredicate.java index e57257f3205..3afcd3c2a43 100644 --- a/src/main/java/seedu/address/model/module/TutorialContainsKeywordPredicate.java +++ b/src/main/java/seedu/address/model/module/TutorialContainsKeywordPredicate.java @@ -11,7 +11,10 @@ public class TutorialContainsKeywordPredicate implements Predicate { private final String keyword; - + /** + * Constructs a {@code TutorialContainsKeywordPredicate} with the specified keyword. + * @param keyword The keyword to be used for testing. + */ public TutorialContainsKeywordPredicate(String keyword) { this.keyword = keyword; } diff --git a/src/main/java/seedu/address/model/person/EmailContainsKeywordPredicate.java b/src/main/java/seedu/address/model/person/EmailContainsKeywordPredicate.java index 753c2d8b94e..d6d1975081f 100644 --- a/src/main/java/seedu/address/model/person/EmailContainsKeywordPredicate.java +++ b/src/main/java/seedu/address/model/person/EmailContainsKeywordPredicate.java @@ -12,6 +12,10 @@ public class EmailContainsKeywordPredicate implements Predicate { private final String keyword; + /** + * Constructs an {@code EmailContainsKeywordPredicate} with the specified keyword. + * @param keyword The keyword to be used for testing. + */ public EmailContainsKeywordPredicate(String keyword) { this.keyword = keyword; } diff --git a/src/main/java/seedu/address/model/person/NameContainsKeywordPredicate.java b/src/main/java/seedu/address/model/person/NameContainsKeywordPredicate.java index aed5db13f0b..9f8dce828f3 100644 --- a/src/main/java/seedu/address/model/person/NameContainsKeywordPredicate.java +++ b/src/main/java/seedu/address/model/person/NameContainsKeywordPredicate.java @@ -12,6 +12,10 @@ public class NameContainsKeywordPredicate implements Predicate { private final String keyword; + /** + * Constructs a {@code NameContainsKeywordPredicate} with the specified keyword. + * @param keyword The keyword to be used for testing. + */ public NameContainsKeywordPredicate(String keyword) { this.keyword = keyword; } diff --git a/src/main/java/seedu/address/model/person/StudentIdContainsKeywordPredicate.java b/src/main/java/seedu/address/model/person/StudentIdContainsKeywordPredicate.java index dc2eb9833d2..a85f565286c 100644 --- a/src/main/java/seedu/address/model/person/StudentIdContainsKeywordPredicate.java +++ b/src/main/java/seedu/address/model/person/StudentIdContainsKeywordPredicate.java @@ -16,6 +16,11 @@ public StudentIdContainsKeywordPredicate(String keyword) { this.keyword = keyword; } + /** + * Tests if the given {@code Person}'s student ID matches the keyword. + * @param person The person to be tested. + * @return True if the person's student ID matches the keyword, false otherwise. + */ @Override public boolean test(Person person) { return StringUtil.containsPartialWordIgnoreCase(person.getStudentId().value, keyword); diff --git a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java b/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java index 3b66418affb..8152d3bed21 100644 --- a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java +++ b/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java @@ -27,7 +27,7 @@ class JsonSerializableAddressBook { private final List modules = new ArrayList<>(); /** - * Constructs a {@code JsonSerializableAddressBook} with the given persons. + * Constructs a {@code JsonSerializableAddressBook} with the given persons and modules. */ @JsonCreator public JsonSerializableAddressBook(@JsonProperty("persons") List persons, diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index bd54605911e..ed2f9479459 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -133,15 +133,26 @@ void fillInnerParts() { commandBoxPlaceholder.getChildren().add(commandBox.getRoot()); } + /** + * Determines whether to initially display the module list panel. + * + * @return True if the module list panel should be initially displayed, false otherwise. + */ private boolean initiallyDisplayModuleListPanel() { return logic.isInitialModuleListPanelDisplayed(); } + /** + * Switches to the person list panel. + */ private void switchToPersonListPanel() { personListPanel = new PersonListPanel(logic.getFilteredPersonList()); personListPanelPlaceholder.getChildren().add(personListPanel.getRoot()); } + /** + * Switches to the module list panel. + */ private void switchToModuleListPanel() { ObservableList moduleObservableList = FXCollections .observableList(logic.getAddressBook().getModuleList()); @@ -173,6 +184,9 @@ public void handleHelp() { } } + /** + * Shows the primary stage of the application. + */ void show() { primaryStage.show(); } @@ -228,6 +242,10 @@ private CommandResult executeCommand(String commandText) throws CommandException } } + /** + * Clears the placeholders for the person list panel and module list panel, removing all UI components + * currently displayed in these placeholders. + */ private void clearPanels() { personListPanelPlaceholder.getChildren().clear(); moduleListPanelPlaceholder.getChildren().clear(); diff --git a/src/test/java/seedu/address/AppParametersTest.java b/src/test/java/seedu/address/AppParametersTest.java index 133cc008bce..5845e8c6d11 100644 --- a/src/test/java/seedu/address/AppParametersTest.java +++ b/src/test/java/seedu/address/AppParametersTest.java @@ -14,6 +14,9 @@ import javafx.application.Application; +/** + * Test class for AppParameters. It tests the parsing and equality functionality of the AppParameters class. + */ public class AppParametersTest { private final ParametersStub parametersStub = new ParametersStub(); @@ -68,6 +71,10 @@ public void equals() { assertFalse(appParameters.equals(otherAppParameters)); } + /** + * A stub class extending Application.Parameters for testing purposes. + * It provides a way to set named parameters for testing the parsing functionality of AppParameters. + */ private static class ParametersStub extends Application.Parameters { private Map namedParameters = new HashMap<>(); diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/address/logic/LogicManagerTest.java index 01a04e0bc67..4652c27a6fb 100644 --- a/src/test/java/seedu/address/logic/LogicManagerTest.java +++ b/src/test/java/seedu/address/logic/LogicManagerTest.java @@ -34,6 +34,9 @@ import seedu.address.storage.StorageManager; import seedu.address.testutil.PersonBuilder; +/** + * Contains unit tests for the LogicManager class. + */ public class LogicManagerTest { private static final IOException DUMMY_IO_EXCEPTION = new IOException("dummy IO exception"); private static final IOException DUMMY_AD_EXCEPTION = new AccessDeniedException("dummy access denied exception"); diff --git a/src/test/java/seedu/address/logic/commands/AddClassCommandTest.java b/src/test/java/seedu/address/logic/commands/AddClassCommandTest.java index ca2e5dac49f..e04b52616dd 100644 --- a/src/test/java/seedu/address/logic/commands/AddClassCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddClassCommandTest.java @@ -24,7 +24,8 @@ import seedu.address.model.module.TutorialClass; /** - * Contains integration tests (interaction with the Model) and unit tests for AddClassCommand. + * Contains integration tests (interaction with the Model) for + * {@code AddClassCommand}. */ public class AddClassCommandTest { private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); diff --git a/src/test/java/seedu/address/logic/commands/AddCommandTest.java b/src/test/java/seedu/address/logic/commands/AddCommandTest.java index c72568729da..952ce1127d8 100644 --- a/src/test/java/seedu/address/logic/commands/AddCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddCommandTest.java @@ -26,6 +26,10 @@ import seedu.address.model.person.Person; import seedu.address.testutil.PersonBuilder; +/** + * Contains integration tests (interaction with the Model) for + * {@code AddCommand}. + */ public class AddCommandTest { @Test diff --git a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java index 80d9110c03a..5696f4d52a3 100644 --- a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java @@ -10,6 +10,10 @@ import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; +/** + * Contains integration tests (interaction with the Model) for + * {@code ClearCommand}. + */ public class ClearCommandTest { @Test diff --git a/src/test/java/seedu/address/logic/commands/CommandResultTest.java b/src/test/java/seedu/address/logic/commands/CommandResultTest.java index 7b8c7cd4546..27b8d9c4741 100644 --- a/src/test/java/seedu/address/logic/commands/CommandResultTest.java +++ b/src/test/java/seedu/address/logic/commands/CommandResultTest.java @@ -7,6 +7,10 @@ import org.junit.jupiter.api.Test; +/** + * Contains integration tests (interaction with the Model) for + * {@code CommandResult}. + */ public class CommandResultTest { @Test public void equals() { diff --git a/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java index 930a7714e7d..3d8140f9a53 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteClassCommandTest.java @@ -23,7 +23,8 @@ import seedu.address.model.module.TutorialClass; /** - * Contains integration tests (interaction with the Model) and unit tests for AddClassCommand. + * Contains integration tests (interaction with the Model) for + * {@code DeleteClassCommand}. */ public class DeleteClassCommandTest { private final Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); diff --git a/src/test/java/seedu/address/logic/commands/DeleteStudentCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/DeleteStudentCommandIntegrationTest.java index d4d20a9c19c..3689f0d1aa3 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteStudentCommandIntegrationTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteStudentCommandIntegrationTest.java @@ -20,7 +20,7 @@ /** * Contains integration tests (interaction with the Model) for - * {@code AddCommand}. + * {@code DeleteStudentCommand}. */ public class DeleteStudentCommandIntegrationTest { diff --git a/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java b/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java index 63468c462c8..eb996565858 100644 --- a/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java +++ b/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java @@ -14,6 +14,10 @@ import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; import seedu.address.testutil.EditPersonDescriptorBuilder; +/** + * JUnit test class for {@code EditPersonDescriptor}. + * This class tests the behavior of the {@code EditPersonDescriptor} class. + */ public class EditPersonDescriptorTest { @Test diff --git a/src/test/java/seedu/address/logic/commands/ExitCommandTest.java b/src/test/java/seedu/address/logic/commands/ExitCommandTest.java index 9533c473875..f4f0852f027 100644 --- a/src/test/java/seedu/address/logic/commands/ExitCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ExitCommandTest.java @@ -8,6 +8,10 @@ import seedu.address.model.Model; import seedu.address.model.ModelManager; +/** + * JUnit test class for {@code ExitCommand}. + * This class tests the behavior of the {@code ExitCommand} class. + */ public class ExitCommandTest { private Model model = new ModelManager(); private Model expectedModel = new ModelManager(); diff --git a/src/test/java/seedu/address/logic/commands/HelpCommandTest.java b/src/test/java/seedu/address/logic/commands/HelpCommandTest.java index 4904fc4352e..34515f9c4a1 100644 --- a/src/test/java/seedu/address/logic/commands/HelpCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/HelpCommandTest.java @@ -8,6 +8,10 @@ import seedu.address.model.Model; import seedu.address.model.ModelManager; +/** + * Contains integration tests (interaction with the Model) for + * {@code HelpCommand}. + */ public class HelpCommandTest { private Model model = new ModelManager(); private Model expectedModel = new ModelManager(); diff --git a/src/test/java/seedu/address/logic/commands/ListClassesCommandTest.java b/src/test/java/seedu/address/logic/commands/ListClassesCommandTest.java index 4418c33235a..ec93b1e43b3 100644 --- a/src/test/java/seedu/address/logic/commands/ListClassesCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ListClassesCommandTest.java @@ -16,6 +16,10 @@ import seedu.address.model.module.TutorialClass; import seedu.address.testutil.TypicalModules; +/** + * Contains integration tests (interaction with the Model) for + * {@code ListClassCommand}. + */ public class ListClassesCommandTest { private Model model; diff --git a/src/test/java/seedu/address/logic/commands/ListCommandTest.java b/src/test/java/seedu/address/logic/commands/ListCommandTest.java index 435ff1f7275..2cb48aa8018 100644 --- a/src/test/java/seedu/address/logic/commands/ListCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ListCommandTest.java @@ -13,7 +13,8 @@ import seedu.address.model.UserPrefs; /** - * Contains integration tests (interaction with the Model) and unit tests for ListCommand. + * Contains integration tests (interaction with the Model) for + * {@code ListCommand}. */ public class ListCommandTest { diff --git a/src/test/java/seedu/address/logic/parser/AddClassCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddClassCommandParserTest.java index 592822fc0a4..d671e5ba195 100644 --- a/src/test/java/seedu/address/logic/parser/AddClassCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddClassCommandParserTest.java @@ -16,6 +16,9 @@ import seedu.address.model.module.ModuleCode; import seedu.address.model.module.TutorialClass; +/** + * Contains unit tests for AddClassCommandParser. + */ public class AddClassCommandParserTest { private final AddClassCommandParser parser = new AddClassCommandParser(); diff --git a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java index 67453ba6d4c..6efaf97047a 100644 --- a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java @@ -40,6 +40,9 @@ import seedu.address.model.tag.Tag; import seedu.address.testutil.PersonBuilder; +/** + * Contains unit tests for AddCommandParser. + */ public class AddCommandParserTest { private AddCommandParser parser = new AddCommandParser(); diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 9dd91030ac6..51d3bd2b33d 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -39,6 +39,9 @@ import seedu.address.testutil.PersonBuilder; import seedu.address.testutil.PersonUtil; +/** + * Contains unit tests for AddressBookParser. + */ public class AddressBookParserTest { private final AddressBookParser parser = new AddressBookParser(); diff --git a/src/test/java/seedu/address/logic/parser/ArgumentTokenizerTest.java b/src/test/java/seedu/address/logic/parser/ArgumentTokenizerTest.java index c97308935f5..7086e62d6e5 100644 --- a/src/test/java/seedu/address/logic/parser/ArgumentTokenizerTest.java +++ b/src/test/java/seedu/address/logic/parser/ArgumentTokenizerTest.java @@ -7,6 +7,9 @@ import org.junit.jupiter.api.Test; +/** + * Contains unit tests for ArgumentTokenizer. + */ public class ArgumentTokenizerTest { private final Prefix unknownPrefix = new Prefix("--u"); diff --git a/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java index 6db8ed91245..10f347df9da 100644 --- a/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/DeleteClassCommandParserTest.java @@ -16,6 +16,13 @@ import seedu.address.model.module.ModuleCode; import seedu.address.model.module.TutorialClass; +/** + * As we are only doing white-box testing, our test cases do not cover path variations + * outside of the DeleteClassCommand code. For example, inputs "1" and "1 abc" take the + * same path through the DeleteClassCommand, and therefore we test only one of them. + * The path variation for those two cases occur inside the ParserUtil, and + * therefore should be covered by the ParserUtilTest. + */ public class DeleteClassCommandParserTest { private final DeleteClassCommandParser parser = new DeleteClassCommandParser(); diff --git a/src/test/java/seedu/address/logic/parser/DeleteStudentCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteStudentCommandParserTest.java index 3fbca79e9ab..3d4ff84e93b 100644 --- a/src/test/java/seedu/address/logic/parser/DeleteStudentCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/DeleteStudentCommandParserTest.java @@ -18,8 +18,8 @@ /** * As we are only doing white-box testing, our test cases do not cover path variations - * outside of the DeleteCommand code. For example, inputs "1" and "1 abc" take the - * same path through the DeleteCommand, and therefore we test only one of them. + * outside of the DeleteStudentCommand code. For example, inputs "1" and "1 abc" take the + * same path through the DeleteStudentCommand, and therefore we test only one of them. * The path variation for those two cases occur inside the ParserUtil, and * therefore should be covered by the ParserUtilTest. */ diff --git a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java b/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java index 326b87ef16b..b047913bd69 100644 --- a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java @@ -39,6 +39,9 @@ import seedu.address.model.tag.Tag; import seedu.address.testutil.EditPersonDescriptorBuilder; +/** + * Contains unit tests for EditCommandParser. + */ public class EditCommandParserTest { private static final String TAG_EMPTY = " " + PREFIX_TAG; diff --git a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java index d92e64d12f9..385ec568355 100644 --- a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java @@ -11,6 +11,9 @@ import seedu.address.logic.commands.FindCommand; import seedu.address.model.person.NameContainsKeywordsPredicate; +/** + * Contains unit tests for FindCommandParser. + */ public class FindCommandParserTest { private FindCommandParser parser = new FindCommandParser(); diff --git a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java b/src/test/java/seedu/address/logic/parser/ParserUtilTest.java index 7e459d11cf4..96379165cbd 100644 --- a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java +++ b/src/test/java/seedu/address/logic/parser/ParserUtilTest.java @@ -20,6 +20,9 @@ import seedu.address.model.person.StudentId; import seedu.address.model.tag.Tag; +/** + * Contains helper methods for testing parsers. + */ public class ParserUtilTest { private static final String INVALID_NAME = "R@chel"; private static final String INVALID_STUDENT_ID = "+3213321"; diff --git a/src/test/java/seedu/address/logic/parser/SearchStudentCommandParserTest.java b/src/test/java/seedu/address/logic/parser/SearchStudentCommandParserTest.java index 5bd9bfba4e5..57ef0003573 100644 --- a/src/test/java/seedu/address/logic/parser/SearchStudentCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/SearchStudentCommandParserTest.java @@ -18,6 +18,9 @@ import seedu.address.model.person.NameContainsKeywordPredicate; import seedu.address.model.person.StudentIdContainsKeywordPredicate; +/** + * Contains unit tests for SearchStudentCommandParser. + */ public class SearchStudentCommandParserTest { private SearchStudentCommandParser parser = new SearchStudentCommandParser(); diff --git a/src/test/java/seedu/address/model/AddressBookTest.java b/src/test/java/seedu/address/model/AddressBookTest.java index b2817edf5ec..60811bdfcb3 100644 --- a/src/test/java/seedu/address/model/AddressBookTest.java +++ b/src/test/java/seedu/address/model/AddressBookTest.java @@ -23,6 +23,9 @@ import seedu.address.model.person.exceptions.DuplicatePersonException; import seedu.address.testutil.PersonBuilder; +/** + * Contains unit tests for the AddressBook class. + */ public class AddressBookTest { private final AddressBook addressBook = new AddressBook(); diff --git a/src/test/java/seedu/address/model/ModelManagerTest.java b/src/test/java/seedu/address/model/ModelManagerTest.java index 3600d57323f..d4a4a8f1e04 100644 --- a/src/test/java/seedu/address/model/ModelManagerTest.java +++ b/src/test/java/seedu/address/model/ModelManagerTest.java @@ -19,6 +19,9 @@ import seedu.address.model.person.NameContainsKeywordsPredicate; import seedu.address.testutil.AddressBookBuilder; +/** + * Contains unit tests for the ModelManager class. + */ public class ModelManagerTest { private ModelManager modelManager = new ModelManager(); diff --git a/src/test/java/seedu/address/model/UserPrefsTest.java b/src/test/java/seedu/address/model/UserPrefsTest.java index b1307a70d52..2753b3fd0d3 100644 --- a/src/test/java/seedu/address/model/UserPrefsTest.java +++ b/src/test/java/seedu/address/model/UserPrefsTest.java @@ -4,6 +4,9 @@ import org.junit.jupiter.api.Test; +/** + * Contains unit tests for the UserPrefs class. + */ public class UserPrefsTest { @Test diff --git a/src/test/java/seedu/address/model/module/ModuleCodeTest.java b/src/test/java/seedu/address/model/module/ModuleCodeTest.java index 3f8bd8b8918..3f996d24bf0 100644 --- a/src/test/java/seedu/address/model/module/ModuleCodeTest.java +++ b/src/test/java/seedu/address/model/module/ModuleCodeTest.java @@ -7,6 +7,9 @@ import org.junit.jupiter.api.Test; +/** + * Contains unit tests for the ModuleCode class. + */ public class ModuleCodeTest { public static final String VALID_MODULE_CODE = "CS2103T"; diff --git a/src/test/java/seedu/address/model/module/ModuleContainsKeywordPredicateTest.java b/src/test/java/seedu/address/model/module/ModuleContainsKeywordPredicateTest.java index 2406284a9a2..040dca7eea9 100644 --- a/src/test/java/seedu/address/model/module/ModuleContainsKeywordPredicateTest.java +++ b/src/test/java/seedu/address/model/module/ModuleContainsKeywordPredicateTest.java @@ -8,6 +8,9 @@ import seedu.address.testutil.ModuleBuilder; +/** + * Contains unit tests for the ModuleContainsKeywordPredicate class. + */ public class ModuleContainsKeywordPredicateTest { @Test diff --git a/src/test/java/seedu/address/model/module/TutorialClassTest.java b/src/test/java/seedu/address/model/module/TutorialClassTest.java index 3ffa1438963..0e291ef1e66 100644 --- a/src/test/java/seedu/address/model/module/TutorialClassTest.java +++ b/src/test/java/seedu/address/model/module/TutorialClassTest.java @@ -22,6 +22,9 @@ import seedu.address.testutil.ModuleBuilder; import seedu.address.testutil.PersonBuilder; +/** + * Contains unit tests for the TutorialClass class. + */ public class TutorialClassTest { public static final String VALID_TUTORIAL = "T09"; diff --git a/src/test/java/seedu/address/model/module/TutorialContainsKeywordPredicateTest.java b/src/test/java/seedu/address/model/module/TutorialContainsKeywordPredicateTest.java index 73ed96ef280..e7072c6c01a 100644 --- a/src/test/java/seedu/address/model/module/TutorialContainsKeywordPredicateTest.java +++ b/src/test/java/seedu/address/model/module/TutorialContainsKeywordPredicateTest.java @@ -8,6 +8,9 @@ import seedu.address.testutil.ModuleBuilder; +/** + * Contains unit tests for the TutorialContainsKeywordPredicate class. + */ public class TutorialContainsKeywordPredicateTest { @Test diff --git a/src/test/java/seedu/address/model/person/AddressTest.java b/src/test/java/seedu/address/model/person/AddressTest.java index 314885eca26..68ba1f30c08 100644 --- a/src/test/java/seedu/address/model/person/AddressTest.java +++ b/src/test/java/seedu/address/model/person/AddressTest.java @@ -6,6 +6,9 @@ import org.junit.jupiter.api.Test; +/** + * Contains unit tests for the Address class. + */ public class AddressTest { @Test diff --git a/src/test/java/seedu/address/model/person/EmailContainsKeywordPredicateTest.java b/src/test/java/seedu/address/model/person/EmailContainsKeywordPredicateTest.java index b82f0ca624e..4bcc0ff082a 100644 --- a/src/test/java/seedu/address/model/person/EmailContainsKeywordPredicateTest.java +++ b/src/test/java/seedu/address/model/person/EmailContainsKeywordPredicateTest.java @@ -8,6 +8,9 @@ import seedu.address.testutil.PersonBuilder; +/** + * Contains unit tests for the EmailContainsKeywordPredicate class. + */ public class EmailContainsKeywordPredicateTest { @Test public void equals() { diff --git a/src/test/java/seedu/address/model/person/EmailTest.java b/src/test/java/seedu/address/model/person/EmailTest.java index f08cdff0a64..c0733e32228 100644 --- a/src/test/java/seedu/address/model/person/EmailTest.java +++ b/src/test/java/seedu/address/model/person/EmailTest.java @@ -6,6 +6,9 @@ import org.junit.jupiter.api.Test; +/** + * Contains unit tests for the Email class. + */ public class EmailTest { @Test diff --git a/src/test/java/seedu/address/model/person/NameContainsKeywordPredicateTest.java b/src/test/java/seedu/address/model/person/NameContainsKeywordPredicateTest.java index f90147bbe55..78214fdf822 100644 --- a/src/test/java/seedu/address/model/person/NameContainsKeywordPredicateTest.java +++ b/src/test/java/seedu/address/model/person/NameContainsKeywordPredicateTest.java @@ -8,6 +8,9 @@ import seedu.address.testutil.PersonBuilder; +/** + * Contains unit tests for the NameContainsKeywordPredicate class. + */ public class NameContainsKeywordPredicateTest { @Test diff --git a/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java b/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java index 17007f89381..3895de3b0aa 100644 --- a/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java +++ b/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java @@ -12,6 +12,9 @@ import seedu.address.testutil.PersonBuilder; +/** + * Contains unit tests for the NameContainsKeywordsPredicate class. + */ public class NameContainsKeywordsPredicateTest { @Test diff --git a/src/test/java/seedu/address/model/person/NameTest.java b/src/test/java/seedu/address/model/person/NameTest.java index 94e3dd726bd..e4e87e05ec1 100644 --- a/src/test/java/seedu/address/model/person/NameTest.java +++ b/src/test/java/seedu/address/model/person/NameTest.java @@ -6,6 +6,9 @@ import org.junit.jupiter.api.Test; +/** + * Contains unit tests for the Name class. + */ public class NameTest { @Test diff --git a/src/test/java/seedu/address/model/person/PersonTest.java b/src/test/java/seedu/address/model/person/PersonTest.java index a10ec4a3f82..7bfc5520032 100644 --- a/src/test/java/seedu/address/model/person/PersonTest.java +++ b/src/test/java/seedu/address/model/person/PersonTest.java @@ -16,6 +16,9 @@ import seedu.address.testutil.PersonBuilder; +/** + * Contains unit tests for the Person class. + */ public class PersonTest { @Test diff --git a/src/test/java/seedu/address/model/person/PhoneTest.java b/src/test/java/seedu/address/model/person/PhoneTest.java index deaaa5ba190..d0ff96db969 100644 --- a/src/test/java/seedu/address/model/person/PhoneTest.java +++ b/src/test/java/seedu/address/model/person/PhoneTest.java @@ -6,6 +6,9 @@ import org.junit.jupiter.api.Test; +/** + * Contains unit tests for the Phone class. + */ public class PhoneTest { @Test diff --git a/src/test/java/seedu/address/model/person/StudentIdContainsKeywordPredicateTest.java b/src/test/java/seedu/address/model/person/StudentIdContainsKeywordPredicateTest.java index c7633ecda6c..b6292f5bc6d 100644 --- a/src/test/java/seedu/address/model/person/StudentIdContainsKeywordPredicateTest.java +++ b/src/test/java/seedu/address/model/person/StudentIdContainsKeywordPredicateTest.java @@ -8,6 +8,9 @@ import seedu.address.testutil.PersonBuilder; +/** + * Contains unit tests for the StudentIdContainsKeywordPredicate class. + */ public class StudentIdContainsKeywordPredicateTest { @Test public void equals() { diff --git a/src/test/java/seedu/address/model/person/UniquePersonListTest.java b/src/test/java/seedu/address/model/person/UniquePersonListTest.java index 29030548b4d..a664ad731f6 100644 --- a/src/test/java/seedu/address/model/person/UniquePersonListTest.java +++ b/src/test/java/seedu/address/model/person/UniquePersonListTest.java @@ -21,6 +21,9 @@ import seedu.address.model.person.exceptions.PersonNotFoundException; import seedu.address.testutil.PersonBuilder; +/** + * Contains unit tests for the UniquePersonList class. + */ public class UniquePersonListTest { private final UniquePersonList uniquePersonList = new UniquePersonList(); diff --git a/src/test/java/seedu/address/testutil/TypicalModules.java b/src/test/java/seedu/address/testutil/TypicalModules.java index 8976a7025c0..1100cd4a225 100644 --- a/src/test/java/seedu/address/testutil/TypicalModules.java +++ b/src/test/java/seedu/address/testutil/TypicalModules.java @@ -13,6 +13,11 @@ public class TypicalModules { public static final TutorialClass CS2103T_TUT1 = new TutorialClass("T01"); public static final TutorialClass CS2103T_TUT2 = new TutorialClass("T02"); + /** + * Returns a list of typical modules with their associated tutorial classes. + * + * @return The list of typical modules. + */ public static List getTypicalModules() { List modules = new ArrayList<>(); ModuleCode cs2103t = new ModuleCode(CS2103T_CODE, "T09"); diff --git a/src/test/java/seedu/address/testutil/TypicalPersons.java b/src/test/java/seedu/address/testutil/TypicalPersons.java index 4a0348ef06c..1d8d6a90206 100644 --- a/src/test/java/seedu/address/testutil/TypicalPersons.java +++ b/src/test/java/seedu/address/testutil/TypicalPersons.java @@ -72,6 +72,11 @@ public static AddressBook getTypicalAddressBook() { return ab; } + /** + * Returns a list of typical persons. + * + * @return The list of typical persons. + */ public static List getTypicalPersons() { return new ArrayList<>(Arrays.asList(ALICE, BENSON, CARL, DANIEL, ELLE, FIONA, GEORGE)); } diff --git a/src/test/java/seedu/address/ui/JavaFxInitializer.java b/src/test/java/seedu/address/ui/JavaFxInitializer.java deleted file mode 100644 index 8f606099c96..00000000000 --- a/src/test/java/seedu/address/ui/JavaFxInitializer.java +++ /dev/null @@ -1,15 +0,0 @@ -package seedu.address.ui; - -import org.junit.jupiter.api.BeforeAll; - -import javafx.embed.swing.JFXPanel; -/** - * The JavaFxInitializer class provides a method to initialize the JavaFX environment - * before running any JavaFX-related tests. - */ -public class JavaFxInitializer { - @BeforeAll - public static void initializeJavaFX() { - new JFXPanel(); // Initializes JavaFX environment - } -} diff --git a/src/test/java/seedu/address/ui/UiPartTest.java b/src/test/java/seedu/address/ui/UiPartTest.java index 33d82d911b8..4b4fe7795ce 100644 --- a/src/test/java/seedu/address/ui/UiPartTest.java +++ b/src/test/java/seedu/address/ui/UiPartTest.java @@ -13,6 +13,9 @@ import javafx.fxml.FXML; import seedu.address.MainApp; +/** + * Test class for UiPart. Used for testing UiPart functionality. + */ public class UiPartTest { private static final String MISSING_FILE_PATH = "UiPartTest/missingFile.fxml"; From 976dd0eb36989e4023ea8af3b25b2785517107b1 Mon Sep 17 00:00:00 2001 From: qinxutan Date: Tue, 19 Mar 2024 22:44:28 +0800 Subject: [PATCH 14/33] Resolve merge conflicts --- src/main/java/seedu/address/logic/Logic.java | 1 + src/main/java/seedu/address/model/Model.java | 1 + src/main/java/seedu/address/ui/MainWindow.java | 5 ----- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/address/logic/Logic.java b/src/main/java/seedu/address/logic/Logic.java index 972f2edb240..e5a50ecf74c 100644 --- a/src/main/java/seedu/address/logic/Logic.java +++ b/src/main/java/seedu/address/logic/Logic.java @@ -46,6 +46,7 @@ public interface Logic { * Set the user prefs' GUI settings. */ void setGuiSettings(GuiSettings guiSettings); + /** * Checks if the initial module list panel is displayed. */ diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index 04c36e0c67b..3ca8f3f5360 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -94,6 +94,7 @@ public interface Model { /** Returns an unmodifiable view of the filtered person list */ ObservableList getFilteredPersonList(); + /** Returns an unmodifiable view of the filtered module list */ ObservableList getFilteredModuleList(); diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index ed2f9479459..d33bfea5c4c 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -241,11 +241,6 @@ private CommandResult executeCommand(String commandText) throws CommandException throw e; } } - - /** - * Clears the placeholders for the person list panel and module list panel, removing all UI components - * currently displayed in these placeholders. - */ private void clearPanels() { personListPanelPlaceholder.getChildren().clear(); moduleListPanelPlaceholder.getChildren().clear(); From 6d73be1c3960ea65f53c592fb36f27763040cbcd Mon Sep 17 00:00:00 2001 From: whelan-low Date: Tue, 19 Mar 2024 22:46:08 +0800 Subject: [PATCH 15/33] Modify MainWindow to display modules when /add_class or /delete_class is used too --- src/main/java/seedu/address/model/person/Address.java | 1 - src/main/java/seedu/address/ui/MainWindow.java | 7 +++++-- src/main/java/seedu/address/ui/PersonCard.java | 1 - 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/address/model/person/Address.java b/src/main/java/seedu/address/model/person/Address.java index 469a2cc9a1e..5fbef70f486 100644 --- a/src/main/java/seedu/address/model/person/Address.java +++ b/src/main/java/seedu/address/model/person/Address.java @@ -2,7 +2,6 @@ import static java.util.Objects.requireNonNull; import static seedu.address.commons.util.AppUtil.checkArgument; - /** * Represents a Person's address in the address book. * Guarantees: immutable; is valid as declared in {@link #isValidAddress(String)} diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index bd54605911e..bb6abeae9e7 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -15,7 +15,9 @@ import seedu.address.commons.core.GuiSettings; import seedu.address.commons.core.LogsCenter; import seedu.address.logic.Logic; +import seedu.address.logic.commands.AddClassCommand; import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.DeleteClassCommand; import seedu.address.logic.commands.ListClassesCommand; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.logic.parser.exceptions.ParseException; @@ -214,12 +216,13 @@ private CommandResult executeCommand(String commandText) throws CommandException clearPanels(); - if (commandText.equals(ListClassesCommand.COMMAND_WORD)) { + if (commandText.equals(ListClassesCommand.COMMAND_WORD) + || commandText.split(" ")[0].equals(AddClassCommand.COMMAND_WORD) + || commandText.split(" ")[0].equals(DeleteClassCommand.COMMAND_WORD)) { switchToModuleListPanel(); } else { switchToPersonListPanel(); } - return commandResult; } catch (CommandException | ParseException e) { logger.info("An error occurred while executing command: " + commandText); diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java index b3fa4dc9ac0..993d867b765 100644 --- a/src/main/java/seedu/address/ui/PersonCard.java +++ b/src/main/java/seedu/address/ui/PersonCard.java @@ -8,7 +8,6 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Region; import seedu.address.model.person.Person; - /** * An UI component that displays information of a {@code Person}. */ From 7754f1aebd79b9e35a45eb728bc2eb142d529e91 Mon Sep 17 00:00:00 2001 From: qinxutan Date: Tue, 19 Mar 2024 22:50:47 +0800 Subject: [PATCH 16/33] no message --- src/main/java/seedu/address/model/Model.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index 3ca8f3f5360..36f21ee00f2 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -94,8 +94,6 @@ public interface Model { /** Returns an unmodifiable view of the filtered person list */ ObservableList getFilteredPersonList(); - - /** Returns an unmodifiable view of the filtered module list */ ObservableList getFilteredModuleList(); /** From 5a7ef2742f18c557964d3d81fcfc954957cc78ff Mon Sep 17 00:00:00 2001 From: qinxutan Date: Tue, 19 Mar 2024 23:08:36 +0800 Subject: [PATCH 17/33] Resolve merge conflicts --- .../java/seedu/address/model/AddressBook.java | 6 ------ src/main/java/seedu/address/model/Model.java | 1 - .../java/seedu/address/model/ModelManager.java | 5 ----- .../seedu/address/model/ReadOnlyAddressBook.java | 8 -------- src/main/java/seedu/address/ui/MainWindow.java | 16 ---------------- 5 files changed, 36 deletions(-) diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index 36ede125f67..0433196b37e 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -52,12 +52,6 @@ public AddressBook(ReadOnlyAddressBook toBeCopied) { public void setPersons(List persons) { this.persons.setPersons(persons); } - - public void setModules(List modules) { - requireNonNull(modules); - this.modules.clear(); - this.modules.addAll(modules); - } /** * Replaces the contents of the module list with {@code modules}. */ diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index 43351574218..306db790641 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -103,7 +103,6 @@ public interface Model { * @throws NullPointerException if {@code predicate} is null. */ void updateFilteredPersonList(Predicate predicate); - void updateFilteredModuleList(Predicate predicate); /** * Updates the filter of the filtered module 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 69e3fbc83ee..3678c7e0ee0 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -143,11 +143,6 @@ public ObservableList getFilteredModuleList() { return filteredModules; } - @Override - public ObservableList getFilteredModuleList() { - return filteredModules; - } - @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 ffd035aaaa7..2aca05fbc4e 100644 --- a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java +++ b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java @@ -28,13 +28,5 @@ public interface ReadOnlyAddressBook { * @return {@code true} if the address book contains the specified module code, {@code false} otherwise. */ boolean hasModule(ModuleCode moduleCode); - - /** - * Adds a module code to the address book. - * - * @param moduleCode The module code to add. - */ - ObservableList getModuleList(); - boolean hasModule(ModuleCode moduleCode); void addModule(ModuleCode moduleCode); } diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index e3d5ceb8672..15090f05cdf 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -133,22 +133,6 @@ void fillInnerParts() { commandBoxPlaceholder.getChildren().add(commandBox.getRoot()); } - private boolean initiallyDisplayModuleListPanel() { - return logic.isInitialModuleListPanelDisplayed(); - } - - private void switchToPersonListPanel() { - personListPanel = new PersonListPanel(logic.getFilteredPersonList()); - personListPanelPlaceholder.getChildren().add(personListPanel.getRoot()); - } - - private void switchToModuleListPanel() { - ObservableList moduleObservableList = FXCollections - .observableList(logic.getAddressBook().getModuleList()); - moduleListPanel = new ModuleListPanel(moduleObservableList); - moduleListPanelPlaceholder.getChildren().add(moduleListPanel.getRoot()); - } - /** * Determines whether to initially display the module list panel. * From 46ae56ae1e705ff32e1e072172c7bbf433ee3119 Mon Sep 17 00:00:00 2001 From: qinxutan <122926007+qinxutan@users.noreply.github.com> Date: Tue, 19 Mar 2024 23:39:02 +0800 Subject: [PATCH 18/33] UI Testcases (#78) * UI Test Cases * Disable GUI testing for linux * Update GUI test cases * Update GUI Tests * Update GUI Tests --------- Co-authored-by: Whelan <111336032+whelan-low@users.noreply.github.com> --- .../java/seedu/address/ui/ModuleCardTest.java | 36 ++++++++++ .../seedu/address/ui/ModuleListPanelTest.java | 70 +++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 src/test/java/seedu/address/ui/ModuleCardTest.java create mode 100644 src/test/java/seedu/address/ui/ModuleListPanelTest.java diff --git a/src/test/java/seedu/address/ui/ModuleCardTest.java b/src/test/java/seedu/address/ui/ModuleCardTest.java new file mode 100644 index 00000000000..2aaa1accfa2 --- /dev/null +++ b/src/test/java/seedu/address/ui/ModuleCardTest.java @@ -0,0 +1,36 @@ +package seedu.address.ui; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledOnOs; +import org.junit.jupiter.api.condition.OS; + +import javafx.embed.swing.JFXPanel; +import seedu.address.model.module.ModuleCode; + +public class ModuleCardTest { + + @BeforeAll + public static void initializeJavaFX() { + // Initialize JavaFX only if not on Linux + if (!OS.LINUX.isCurrentOs()) { + new JFXPanel(); + } + } + + @DisabledOnOs(OS.LINUX) + @Test + public void constructor_validModuleCode_setsModuleCodeAndTutorialClasses() { + if (!Boolean.getBoolean("gui.tests.enabled") || OS.LINUX.isCurrentOs()) { + System.out.println("Skipping GUI test."); + return; + } + ModuleCode moduleCode = new ModuleCode("CS2103"); + ModuleCard moduleCard = new ModuleCard(moduleCode); + assertEquals(moduleCode, moduleCard.moduleCode); + assertEquals(moduleCode.getModule().toString(), moduleCard.moduleCodeLabel.getText()); + assertEquals(moduleCode.getTutorialClasses().toString(), moduleCard.tutorialClassLabel.getText()); + } +} diff --git a/src/test/java/seedu/address/ui/ModuleListPanelTest.java b/src/test/java/seedu/address/ui/ModuleListPanelTest.java new file mode 100644 index 00000000000..01cd92a9389 --- /dev/null +++ b/src/test/java/seedu/address/ui/ModuleListPanelTest.java @@ -0,0 +1,70 @@ +package seedu.address.ui; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.OS; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.embed.swing.JFXPanel; +import seedu.address.model.module.ModuleCode; + +public class ModuleListPanelTest { + + private ModuleListPanel moduleListPanel; + private ObservableList moduleCodes; + + @BeforeAll + public static void initializeJavaFX() { + // Initialize JavaFX only if not on Linux + if (!OS.LINUX.isCurrentOs()) { + new JFXPanel(); + } + } + + @BeforeEach + public void setUp() { + if (!Boolean.getBoolean("gui.tests.enabled") || OS.LINUX.isCurrentOs()) { + System.out.println("Skipping GUI test."); + return; + } + moduleCodes = FXCollections.observableArrayList(); + moduleListPanel = new ModuleListPanel(moduleCodes); + } + + @Test + public void constructor_withListOfModuleCodes_initializesListView() { + if (!Boolean.getBoolean("gui.tests.enabled") || OS.LINUX.isCurrentOs()) { + System.out.println("Skipping GUI test."); + return; + } + assertNotNull(moduleListPanel.moduleListView); + } + + @Test + public void constructor_withListOfModuleCodes_setsCellFactory() { + if (!Boolean.getBoolean("gui.tests.enabled") || OS.LINUX.isCurrentOs()) { + System.out.println("Skipping GUI test."); + return; + } + assertNotNull(moduleListPanel.moduleListView.getCellFactory()); + } + + @Test + public void constructor_withListOfModuleCodes_displaysCorrectModuleCards() { + // Disable GUI testing on Linux + if (!Boolean.getBoolean("gui.tests.enabled") || OS.LINUX.isCurrentOs()) { + System.out.println("Skipping GUI test."); + return; + } + + moduleCodes.add(new ModuleCode("CS2103")); + assertEquals(1, moduleListPanel.moduleListView.getItems().size()); + } +} + + From 770e4fb093d0c5a069b951f058f48385f11c9ab2 Mon Sep 17 00:00:00 2001 From: mahadhir247 <109577376+mahadhir247@users.noreply.github.com> Date: Wed, 20 Mar 2024 00:17:43 +0800 Subject: [PATCH 19/33] Remove find command (#73) * Remove find command Removed find command and it's dependencies. Previous code contained similar instances of NameContainsKeyword(s)Predicate. Removing NameContainsKeywordsPredicate requires removing find command due to it's heavy dependence. Let's, - remove NameContainsKeywordsPredicate - remove FindCommand and FindCommandParser - remove test cases relating to FindCommand - update usages of NameContainsKeywordsPredicate with appropriate use of NameContainsKeywordPredicate * Update message usage for SearchStudentCommand --- .../address/logic/commands/FindCommand.java | 58 ------------ .../logic/commands/SearchStudentCommand.java | 2 +- .../logic/parser/AddressBookParser.java | 4 - .../logic/parser/FindCommandParser.java | 33 ------- .../person/NameContainsKeywordsPredicate.java | 44 --------- .../logic/commands/CommandTestUtil.java | 5 +- .../logic/commands/FindCommandTest.java | 91 ------------------- .../logic/parser/AddressBookParserTest.java | 14 --- .../logic/parser/FindCommandParserTest.java | 37 -------- .../seedu/address/model/ModelManagerTest.java | 5 +- .../NameContainsKeywordsPredicateTest.java | 88 ------------------ 11 files changed, 5 insertions(+), 376 deletions(-) delete mode 100644 src/main/java/seedu/address/logic/commands/FindCommand.java delete mode 100644 src/main/java/seedu/address/logic/parser/FindCommandParser.java delete mode 100644 src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java delete mode 100644 src/test/java/seedu/address/logic/commands/FindCommandTest.java delete mode 100644 src/test/java/seedu/address/logic/parser/FindCommandParserTest.java delete mode 100644 src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/seedu/address/logic/commands/FindCommand.java deleted file mode 100644 index 72b9eddd3a7..00000000000 --- a/src/main/java/seedu/address/logic/commands/FindCommand.java +++ /dev/null @@ -1,58 +0,0 @@ -package seedu.address.logic.commands; - -import static java.util.Objects.requireNonNull; - -import seedu.address.commons.util.ToStringBuilder; -import seedu.address.logic.Messages; -import seedu.address.model.Model; -import seedu.address.model.person.NameContainsKeywordsPredicate; - -/** - * Finds and lists all persons in address book whose name contains any of the argument keywords. - * Keyword matching is case insensitive. - */ -public class FindCommand extends Command { - - public static final String COMMAND_WORD = "find"; - - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose names contain any of " - + "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n" - + "Parameters: KEYWORD [MORE_KEYWORDS]...\n" - + "Example: " + COMMAND_WORD + " alice bob charlie"; - - private final NameContainsKeywordsPredicate predicate; - - public FindCommand(NameContainsKeywordsPredicate predicate) { - this.predicate = predicate; - } - - @Override - public CommandResult execute(Model model) { - requireNonNull(model); - model.updateFilteredPersonList(predicate); - return new CommandResult( - String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size())); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof FindCommand)) { - return false; - } - - FindCommand otherFindCommand = (FindCommand) other; - return predicate.equals(otherFindCommand.predicate); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .add("predicate", predicate) - .toString(); - } -} diff --git a/src/main/java/seedu/address/logic/commands/SearchStudentCommand.java b/src/main/java/seedu/address/logic/commands/SearchStudentCommand.java index b3042086e02..da151ebf71c 100644 --- a/src/main/java/seedu/address/logic/commands/SearchStudentCommand.java +++ b/src/main/java/seedu/address/logic/commands/SearchStudentCommand.java @@ -22,7 +22,7 @@ public class SearchStudentCommand extends Command { + "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n" + "Only one attribute can be matched per search query.\n" + "Partial matches are also displayed.\n" - + "Parameters: [name/NAME] [id/STUDENT_ID] [email/EMAIL] [module/MODULE_CODE] [tutorial/TUTORIAL_CLASS]\n" + + "Parameters: [name/NAME] [id/STUDENT_ID] [email/EMAIL]\n" + "Example: " + COMMAND_WORD + " id/A012345A"; private final Predicate predicate; diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 326c9d22737..766794f3dc2 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -16,7 +16,6 @@ import seedu.address.logic.commands.DeleteCommand; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.ExitCommand; -import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListClassesCommand; import seedu.address.logic.commands.ListCommand; @@ -77,9 +76,6 @@ public Command parseCommand(String userInput) throws ParseException { case DeleteStudentCommand.COMMAND_WORD: return new DeleteStudentCommandParser().parse(arguments); - case FindCommand.COMMAND_WORD: - return new FindCommandParser().parse(arguments); - case AddClassCommand.COMMAND_WORD: return new AddClassCommandParser().parse(arguments); diff --git a/src/main/java/seedu/address/logic/parser/FindCommandParser.java b/src/main/java/seedu/address/logic/parser/FindCommandParser.java deleted file mode 100644 index 2867bde857b..00000000000 --- a/src/main/java/seedu/address/logic/parser/FindCommandParser.java +++ /dev/null @@ -1,33 +0,0 @@ -package seedu.address.logic.parser; - -import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; - -import java.util.Arrays; - -import seedu.address.logic.commands.FindCommand; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.NameContainsKeywordsPredicate; - -/** - * Parses input arguments and creates a new FindCommand object - */ -public class FindCommandParser implements Parser { - - /** - * Parses the given {@code String} of arguments in the context of the FindCommand - * and returns a FindCommand object for execution. - * @throws ParseException if the user input does not conform the expected format - */ - public FindCommand parse(String args) throws ParseException { - String trimmedArgs = args.trim(); - if (trimmedArgs.isEmpty()) { - throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE)); - } - - String[] nameKeywords = trimmedArgs.split("\\s+"); - - return new FindCommand(new NameContainsKeywordsPredicate(Arrays.asList(nameKeywords))); - } - -} diff --git a/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java deleted file mode 100644 index 62d19be2977..00000000000 --- a/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java +++ /dev/null @@ -1,44 +0,0 @@ -package seedu.address.model.person; - -import java.util.List; -import java.util.function.Predicate; - -import seedu.address.commons.util.StringUtil; -import seedu.address.commons.util.ToStringBuilder; - -/** - * Tests that a {@code Person}'s {@code Name} matches any of the keywords given. - */ -public class NameContainsKeywordsPredicate implements Predicate { - private final List keywords; - - public NameContainsKeywordsPredicate(List keywords) { - this.keywords = keywords; - } - - @Override - public boolean test(Person person) { - return keywords.stream() - .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getName().fullName, keyword)); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof NameContainsKeywordsPredicate)) { - return false; - } - - NameContainsKeywordsPredicate otherNameContainsKeywordsPredicate = (NameContainsKeywordsPredicate) other; - return keywords.equals(otherNameContainsKeywordsPredicate.keywords); - } - - @Override - public String toString() { - return new ToStringBuilder(this).add("keywords", keywords).toString(); - } -} diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java index 7e3d7a9117f..7ccade00cfa 100644 --- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java +++ b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java @@ -12,14 +12,13 @@ import static seedu.address.testutil.Assert.assertThrows; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.AddressBook; import seedu.address.model.Model; -import seedu.address.model.person.NameContainsKeywordsPredicate; +import seedu.address.model.person.NameContainsKeywordPredicate; import seedu.address.model.person.Person; import seedu.address.testutil.EditPersonDescriptorBuilder; @@ -138,7 +137,7 @@ public static void showPersonAtIndex(Model model, Index targetIndex) { Person person = model.getFilteredPersonList().get(targetIndex.getZeroBased()); final String[] splitName = person.getName().fullName.split("\\s+"); - model.updateFilteredPersonList(new NameContainsKeywordsPredicate(Arrays.asList(splitName[0]))); + model.updateFilteredPersonList(new NameContainsKeywordPredicate(splitName[0])); assertEquals(1, model.getFilteredPersonList().size()); } diff --git a/src/test/java/seedu/address/logic/commands/FindCommandTest.java b/src/test/java/seedu/address/logic/commands/FindCommandTest.java deleted file mode 100644 index b8b7dbba91a..00000000000 --- a/src/test/java/seedu/address/logic/commands/FindCommandTest.java +++ /dev/null @@ -1,91 +0,0 @@ -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.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.testutil.TypicalPersons.CARL; -import static seedu.address.testutil.TypicalPersons.ELLE; -import static seedu.address.testutil.TypicalPersons.FIONA; -import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; - -import java.util.Arrays; -import java.util.Collections; - -import org.junit.jupiter.api.Test; - -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.UserPrefs; -import seedu.address.model.person.NameContainsKeywordsPredicate; - -/** - * Contains integration tests (interaction with the Model) for {@code FindCommand}. - */ -public class FindCommandTest { - private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); - private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs()); - - @Test - public void equals() { - NameContainsKeywordsPredicate firstPredicate = - new NameContainsKeywordsPredicate(Collections.singletonList("first")); - NameContainsKeywordsPredicate secondPredicate = - new NameContainsKeywordsPredicate(Collections.singletonList("second")); - - FindCommand findFirstCommand = new FindCommand(firstPredicate); - FindCommand findSecondCommand = new FindCommand(secondPredicate); - - // same object -> returns true - assertTrue(findFirstCommand.equals(findFirstCommand)); - - // same values -> returns true - FindCommand findFirstCommandCopy = new FindCommand(firstPredicate); - assertTrue(findFirstCommand.equals(findFirstCommandCopy)); - - // different types -> returns false - assertFalse(findFirstCommand.equals(1)); - - // null -> returns false - assertFalse(findFirstCommand.equals(null)); - - // different person -> returns false - assertFalse(findFirstCommand.equals(findSecondCommand)); - } - - @Test - public void execute_zeroKeywords_noPersonFound() { - String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0); - NameContainsKeywordsPredicate predicate = preparePredicate(" "); - FindCommand command = new FindCommand(predicate); - expectedModel.updateFilteredPersonList(predicate); - assertCommandSuccess(command, model, expectedMessage, expectedModel); - assertEquals(Collections.emptyList(), model.getFilteredPersonList()); - } - - @Test - public void execute_multipleKeywords_multiplePersonsFound() { - String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 3); - NameContainsKeywordsPredicate predicate = preparePredicate("Kurz Elle Kunz"); - FindCommand command = new FindCommand(predicate); - expectedModel.updateFilteredPersonList(predicate); - assertCommandSuccess(command, model, expectedMessage, expectedModel); - assertEquals(Arrays.asList(CARL, ELLE, FIONA), model.getFilteredPersonList()); - } - - @Test - public void toStringMethod() { - NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Arrays.asList("keyword")); - FindCommand findCommand = new FindCommand(predicate); - String expected = FindCommand.class.getCanonicalName() + "{predicate=" + predicate + "}"; - assertEquals(expected, findCommand.toString()); - } - - /** - * Parses {@code userInput} into a {@code NameContainsKeywordsPredicate}. - */ - private NameContainsKeywordsPredicate preparePredicate(String userInput) { - return new NameContainsKeywordsPredicate(Arrays.asList(userInput.split("\\s+"))); - } -} diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 51d3bd2b33d..3d182d57c6f 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -10,10 +10,6 @@ import static seedu.address.testutil.Assert.assertThrows; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - import org.junit.jupiter.api.Test; import seedu.address.logic.commands.AddClassCommand; @@ -24,7 +20,6 @@ import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; import seedu.address.logic.commands.ExitCommand; -import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListClassesCommand; import seedu.address.logic.commands.ListCommand; @@ -33,7 +28,6 @@ import seedu.address.model.module.ModuleCode; import seedu.address.model.module.TutorialClass; import seedu.address.model.person.NameContainsKeywordPredicate; -import seedu.address.model.person.NameContainsKeywordsPredicate; import seedu.address.model.person.Person; import seedu.address.testutil.EditPersonDescriptorBuilder; import seedu.address.testutil.PersonBuilder; @@ -81,14 +75,6 @@ public void parseCommand_exit() throws Exception { assertTrue(parser.parseCommand(ExitCommand.COMMAND_WORD + " 3") instanceof ExitCommand); } - @Test - public void parseCommand_find() throws Exception { - List keywords = Arrays.asList("foo", "bar", "baz"); - FindCommand command = (FindCommand) parser.parseCommand( - FindCommand.COMMAND_WORD + " " + keywords.stream().collect(Collectors.joining(" "))); - assertEquals(new FindCommand(new NameContainsKeywordsPredicate(keywords)), command); - } - @Test public void parseCommand_searchStudent() throws Exception { String keyword = "foo"; diff --git a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java deleted file mode 100644 index 385ec568355..00000000000 --- a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package seedu.address.logic.parser; - -import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; - -import java.util.Arrays; - -import org.junit.jupiter.api.Test; - -import seedu.address.logic.commands.FindCommand; -import seedu.address.model.person.NameContainsKeywordsPredicate; - -/** - * Contains unit tests for FindCommandParser. - */ -public class FindCommandParserTest { - - private FindCommandParser parser = new FindCommandParser(); - - @Test - public void parse_emptyArg_throwsParseException() { - assertParseFailure(parser, " ", String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE)); - } - - @Test - public void parse_validArgs_returnsFindCommand() { - // no leading and trailing whitespaces - FindCommand expectedFindCommand = - new FindCommand(new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob"))); - assertParseSuccess(parser, "Alice Bob", expectedFindCommand); - - // multiple whitespaces between keywords - assertParseSuccess(parser, " \n Alice \n \t Bob \t", expectedFindCommand); - } - -} diff --git a/src/test/java/seedu/address/model/ModelManagerTest.java b/src/test/java/seedu/address/model/ModelManagerTest.java index d4a4a8f1e04..7547d3af800 100644 --- a/src/test/java/seedu/address/model/ModelManagerTest.java +++ b/src/test/java/seedu/address/model/ModelManagerTest.java @@ -11,12 +11,11 @@ import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; import org.junit.jupiter.api.Test; import seedu.address.commons.core.GuiSettings; -import seedu.address.model.person.NameContainsKeywordsPredicate; +import seedu.address.model.person.NameContainsKeywordPredicate; import seedu.address.testutil.AddressBookBuilder; /** @@ -126,7 +125,7 @@ public void equals() { // different filteredList -> returns false String[] keywords = ALICE.getName().fullName.split("\\s+"); - modelManager.updateFilteredPersonList(new NameContainsKeywordsPredicate(Arrays.asList(keywords))); + modelManager.updateFilteredPersonList(new NameContainsKeywordPredicate(keywords[0])); assertFalse(modelManager.equals(new ModelManager(addressBook, userPrefs))); // resets modelManager to initial state for upcoming tests diff --git a/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java b/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java deleted file mode 100644 index 3895de3b0aa..00000000000 --- a/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java +++ /dev/null @@ -1,88 +0,0 @@ -package seedu.address.model.person; - -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 java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.junit.jupiter.api.Test; - -import seedu.address.testutil.PersonBuilder; - -/** - * Contains unit tests for the NameContainsKeywordsPredicate class. - */ -public class NameContainsKeywordsPredicateTest { - - @Test - public void equals() { - List firstPredicateKeywordList = Collections.singletonList("first"); - List secondPredicateKeywordList = Arrays.asList("first", "second"); - - NameContainsKeywordsPredicate firstPredicate = new NameContainsKeywordsPredicate(firstPredicateKeywordList); - NameContainsKeywordsPredicate secondPredicate = new NameContainsKeywordsPredicate(secondPredicateKeywordList); - - // same object -> returns true - assertTrue(firstPredicate.equals(firstPredicate)); - - // same values -> returns true - NameContainsKeywordsPredicate firstPredicateCopy = new NameContainsKeywordsPredicate(firstPredicateKeywordList); - assertTrue(firstPredicate.equals(firstPredicateCopy)); - - // different types -> returns false - assertFalse(firstPredicate.equals(1)); - - // null -> returns false - assertFalse(firstPredicate.equals(null)); - - // different person -> returns false - assertFalse(firstPredicate.equals(secondPredicate)); - } - - @Test - public void test_nameContainsKeywords_returnsTrue() { - // One keyword - NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Collections.singletonList("Alice")); - assertTrue(predicate.test(new PersonBuilder().withName("Alice Bob").build())); - - // Multiple keywords - predicate = new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob")); - assertTrue(predicate.test(new PersonBuilder().withName("Alice Bob").build())); - - // Only one matching keyword - predicate = new NameContainsKeywordsPredicate(Arrays.asList("Bob", "Carol")); - assertTrue(predicate.test(new PersonBuilder().withName("Alice Carol").build())); - - // Mixed-case keywords - predicate = new NameContainsKeywordsPredicate(Arrays.asList("aLIce", "bOB")); - assertTrue(predicate.test(new PersonBuilder().withName("Alice Bob").build())); - } - - @Test - public void test_nameDoesNotContainKeywords_returnsFalse() { - // Zero keywords - NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Collections.emptyList()); - assertFalse(predicate.test(new PersonBuilder().withName("Alice").build())); - - // Non-matching keyword - predicate = new NameContainsKeywordsPredicate(Arrays.asList("Carol")); - assertFalse(predicate.test(new PersonBuilder().withName("Alice Bob").build())); - - // Keywords match student id, email, but does not match name - predicate = new NameContainsKeywordsPredicate(Arrays.asList("A1234567Z", "alice@email.com")); - assertFalse(predicate.test(new PersonBuilder().withName("Alice").withStudentId("A1234567Z") - .withEmail("alice@email.com").build())); - } - - @Test - public void toStringMethod() { - List keywords = List.of("keyword1", "keyword2"); - NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(keywords); - - String expected = NameContainsKeywordsPredicate.class.getCanonicalName() + "{keywords=" + keywords + "}"; - assertEquals(expected, predicate.toString()); - } -} From 2a18c8a28030bc5a5a2763bbd93d8aefabb8075a Mon Sep 17 00:00:00 2001 From: Jajared Date: Wed, 20 Mar 2024 00:23:49 +0800 Subject: [PATCH 20/33] Added backend integration --- .../AddStudentToClassByEmailCommand.java | 4 +- .../AddStudentToClassByIdCommand.java | 2 +- .../AddStudentToClassByIndexCommand.java | 2 +- .../AddStudentToClassCommand.java | 5 +- .../AddStudentToClassCommandParser.java | 1 + .../java/seedu/address/model/AddressBook.java | 40 +++++++++++- src/main/java/seedu/address/model/Model.java | 13 ++++ .../seedu/address/model/ModelManager.java | 13 ++++ .../address/model/module/ModuleCode.java | 7 +- .../address/model/module/TutorialClass.java | 11 +++- .../address/storage/JsonAdaptedModule.java | 26 +++++++- .../storage/JsonAdaptedTutorialClass.java | 64 +++++++++++++++++++ .../storage/JsonSerializableAddressBook.java | 33 ++++++++++ .../seedu/address/storage/StorageManager.java | 4 +- .../logic/commands/AddCommandTest.java | 11 ++++ .../AddStudentToClassCommandTest.java | 8 ++- .../storage/JsonAdaptedModuleTest.java | 4 +- 17 files changed, 226 insertions(+), 22 deletions(-) create mode 100644 src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java index cabe87b6c75..711813b0bf2 100644 --- a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java @@ -27,6 +27,7 @@ public class AddStudentToClassByEmailCommand extends AddStudentToClassCommand { /** * Adds a student to a class by email. + * * @param email * @param module * @param tutorialClass @@ -49,12 +50,13 @@ public CommandResult execute(Model model) throws CommandException { if (personToAdd == null) { throw new CommandException(String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, email)); } + System.out.println(tutorialClass.getStudents()); if (tutorialClass.hasStudent(personToAdd)) { throw new CommandException( String.format(TutorialClassMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, personToAdd, tutorialClass)); } else { - tutorialClass.addStudent(personToAdd); + model.addPersonToTutorialClass(personToAdd, module, tutorialClass); return new CommandResult( String.format(TutorialClassMessages.MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS, Messages.format(personToAdd), module, diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java index 2201917522c..7f1ee4b252f 100644 --- a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java @@ -51,7 +51,7 @@ public CommandResult execute(Model model) throws CommandException { throw new CommandException(String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, personToAdd, tutorialClass)); } else { - tutorialClass.addStudent(personToAdd); + model.addPersonToTutorialClass(personToAdd, module, tutorialClass); return new CommandResult(String.format(PersonMessages.MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS, Messages.format(personToAdd), module, tutorialClass)); } diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java index 96284b94ea5..ed589c380d9 100644 --- a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java @@ -49,7 +49,7 @@ public CommandResult execute(Model model) throws CommandException { throw new CommandException(String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, personToAdd, tutorialClass)); } else { - tutorialClass.addStudent(personToAdd); + model.addPersonToTutorialClass(personToAdd, module, tutorialClass); return new CommandResult( String.format(PersonMessages.MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS, Messages.format(personToAdd), module, tutorialClass)); diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java index 7cfa24df072..1ef9e50efe8 100644 --- a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassCommand.java @@ -44,14 +44,15 @@ protected ModuleTutorialPair getModuleAndTutorialClass(Model model) throws Comma ModuleCode module = getModule(); TutorialClass tutorialClass = getTutorialClass(); ModuleCode existingModule = model.findModuleFromList(module); + TutorialClass existingTutorialClass = model.findTutorialClassFromList(tutorialClass, existingModule); if (existingModule == null) { throw new CommandException(String.format(ModuleMessages.MESSAGE_MODULE_NOT_FOUND, module)); } - if (!existingModule.hasTutorialClass(tutorialClass)) { + if (existingTutorialClass == null) { throw new CommandException( String.format(ModuleMessages.MESSAGE_TUTORIAL_DOES_NOT_BELONG_TO_MODULE, tutorialClass, module)); } - return new ModuleTutorialPair(module, tutorialClass); + return new ModuleTutorialPair(existingModule, existingTutorialClass); } protected ModuleCode getModule() { diff --git a/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java b/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java index 20c7f5e4985..7841097f1e1 100644 --- a/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java @@ -29,6 +29,7 @@ public class AddStudentToClassCommandParser implements Parser modules) { this.modules.clear(); this.modules.addAll(modules); } + /** * Resets the existing data of this {@code AddressBook} with {@code newData}. */ public void resetData(ReadOnlyAddressBook newData) { requireNonNull(newData); - setPersons(newData.getPersonList()); setModules(newData.getModuleList()); + } //// person-level operations @@ -110,6 +112,23 @@ public ModuleCode findModuleFromList(ModuleCode module) { } return null; } + + /** + * Returns the tutorial object from the tutorial list if it exists. + */ + public TutorialClass findTutorialClassFromList(TutorialClass tutorialClass, ModuleCode moduleCode) { + requireNonNull(tutorialClass); + requireNonNull(moduleCode); + ModuleCode moduleInList = findModuleFromList(moduleCode); + if (moduleInList == null) { + throw new IllegalArgumentException("Module does not exist in the address book."); + } + return moduleInList.getTutorialClasses().stream() + .filter(tutorial -> tutorial.equals(tutorialClass)) + .findFirst() + .orElse(null); + } + /** * Adds a module to the address book. * The module must not already exist in the address book. (TODO) @@ -119,6 +138,25 @@ public void addModule(ModuleCode m) { modules.add(m); } + /** + * Adds a person to the students list of a specific tutorial class within a module. + */ + public void addPersonToTutorialClass(Person person, ModuleCode module, TutorialClass tutorialClass) { + requireNonNull(person); + requireNonNull(module); + requireNonNull(tutorialClass); + + ModuleCode moduleInList = findModuleFromList(module); + if (moduleInList == null) { + throw new IllegalArgumentException("Module does not exist in the address book."); + } + TutorialClass tutorialClassInList = moduleInList.getTutorialClasses().stream() + .filter(tutorial -> tutorial.equals(tutorialClass)) + .findFirst() + .orElse(null); + tutorialClassInList.addStudent(person); + } + /** * Replaces the given person {@code target} in the list with {@code editedPerson}. * {@code target} must exist in the address book. diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index 4e023b3e8f3..edb54425ef6 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -6,6 +6,7 @@ import javafx.collections.ObservableList; import seedu.address.commons.core.GuiSettings; import seedu.address.model.module.ModuleCode; +import seedu.address.model.module.TutorialClass; import seedu.address.model.person.Person; /** @@ -66,6 +67,14 @@ public interface Model { * @return the module if it exists, else return null. */ ModuleCode findModuleFromList(ModuleCode module); + + /** + * Find tutorial object from the list if it exists. Else, returns null. + * @param tutorialClass to be searched + * @param moduleCode to be searched + */ + TutorialClass findTutorialClassFromList(TutorialClass tutorialClass, ModuleCode moduleCode); + /** * Deletes the given person. * The person must exist in the address book. @@ -84,6 +93,10 @@ public interface Model { */ void addModule(ModuleCode module); + /** + * Adds the given person to the given tutorial class in the given module. + */ + void addPersonToTutorialClass(Person person, ModuleCode module, TutorialClass tutorialClass); /** * Replaces the given person {@code target} with {@code editedPerson}. diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index abc0bc8823e..f1039d75b8d 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -12,6 +12,7 @@ import seedu.address.commons.core.GuiSettings; import seedu.address.commons.core.LogsCenter; import seedu.address.model.module.ModuleCode; +import seedu.address.model.module.TutorialClass; import seedu.address.model.person.Person; @@ -101,6 +102,13 @@ public ModuleCode findModuleFromList(ModuleCode module) { requireNonNull(module); return addressBook.findModuleFromList(module); } + + @Override + public TutorialClass findTutorialClassFromList(TutorialClass tutorialClass, ModuleCode moduleCode) { + requireAllNonNull(tutorialClass, moduleCode); + return addressBook.findTutorialClassFromList(tutorialClass, moduleCode); + } + @Override public void deletePerson(Person target) { addressBook.removePerson(target); @@ -117,6 +125,11 @@ public void addModule(ModuleCode module) { addressBook.addModule(module); } + @Override + public void addPersonToTutorialClass(Person person, ModuleCode module, TutorialClass tutorialClass) { + addressBook.addPersonToTutorialClass(person, module, tutorialClass); + } + @Override public void setPerson(Person target, Person editedPerson) { requireAllNonNull(target, editedPerson); diff --git a/src/main/java/seedu/address/model/module/ModuleCode.java b/src/main/java/seedu/address/model/module/ModuleCode.java index ebdad1d4faa..ac834ea9e7e 100644 --- a/src/main/java/seedu/address/model/module/ModuleCode.java +++ b/src/main/java/seedu/address/model/module/ModuleCode.java @@ -120,12 +120,7 @@ public int hashCode() { * @return true if the class name is in the list. False otherwise. */ public boolean hasTutorialClass(TutorialClass tutorialClass) { - for (TutorialClass tutorialClassInModule : tutorialClasses) { - if (tutorialClass.equals(tutorialClassInModule)) { - return true; - } - } - return false; + return tutorialClasses.contains(tutorialClass); } diff --git a/src/main/java/seedu/address/model/module/TutorialClass.java b/src/main/java/seedu/address/model/module/TutorialClass.java index 5be306a29b0..4c24ce39853 100644 --- a/src/main/java/seedu/address/model/module/TutorialClass.java +++ b/src/main/java/seedu/address/model/module/TutorialClass.java @@ -34,6 +34,14 @@ public TutorialClass() { this.students = new ArrayList<>(); } + /** + * Set students to the tutorial class + * @param students + */ + public void setStudents(ArrayList students) { + this.students.addAll(students); + } + /** * A constructor for TutorialClass. Creates an empty tutorial class with no @@ -77,7 +85,6 @@ public ArrayList getStudents() { */ public void addStudent(Person student) { students.add(student); - } /** @@ -106,7 +113,7 @@ public boolean equals(Object other) { } TutorialClass otherTutorialClass = (TutorialClass) other; - return tutorialName.equals(otherTutorialClass.tutorialName); + return tutorialName.equals(otherTutorialClass.tutorialName) && students.equals(otherTutorialClass.students); } @Override diff --git a/src/main/java/seedu/address/storage/JsonAdaptedModule.java b/src/main/java/seedu/address/storage/JsonAdaptedModule.java index dd564610b1d..7827ad0ff24 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.stream.Collectors; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -17,14 +18,14 @@ class JsonAdaptedModule { public static final String MISSING_FIELD_MESSAGE_FORMAT = "Module name is missing!"; private final String name; - private final ArrayList tutorialClasses; + private final ArrayList tutorialClasses; /** * Constructs a {@code JsonAdaptedModule} with the given module details. */ @JsonCreator public JsonAdaptedModule(@JsonProperty("name") String name, @JsonProperty("tutorialClasses") - ArrayList tutorialClasses) { + ArrayList tutorialClasses) { this.name = name; this.tutorialClasses = tutorialClasses; } @@ -34,7 +35,22 @@ public JsonAdaptedModule(@JsonProperty("name") String name, @JsonProperty("tutor */ public JsonAdaptedModule(ModuleCode source) { name = source.toString(); - this.tutorialClasses = source.getTutorialClasses(); + this.tutorialClasses = source.getTutorialClasses().stream().map(JsonAdaptedTutorialClass::new) + .collect(Collectors.toCollection(ArrayList::new)); + } + + /** + * Retrieves module name from the module. + */ + public String getModuleName() { + return name; + } + + /** + * Retrieves tutorial classes from the module. + */ + public ArrayList getTutorialClasses() { + return tutorialClasses; } /** @@ -46,6 +62,10 @@ public ModuleCode toModelType() throws IllegalValueException { if (!ModuleCode.isValidModuleCode(name)) { throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, name)); } + ArrayList tutorialClasses = new ArrayList<>(); + for (JsonAdaptedTutorialClass tutorialClass : this.tutorialClasses) { + tutorialClasses.add(tutorialClass.toModelType()); + } return new ModuleCode(name, tutorialClasses); } } diff --git a/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java b/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java new file mode 100644 index 00000000000..444427ef70b --- /dev/null +++ b/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java @@ -0,0 +1,64 @@ +package seedu.address.storage; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.module.TutorialClass; +import seedu.address.model.person.Person; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class JsonAdaptedTutorialClass { + + private final String tutorialName; + private final List students; + + @JsonCreator + public JsonAdaptedTutorialClass(@JsonProperty("tutorialName") String tutorialName, + @JsonProperty("students") List students) { + this.tutorialName = tutorialName; + this.students = students != null ? new ArrayList<>(students) : new ArrayList<>(); + } + + public JsonAdaptedTutorialClass(TutorialClass source) { + this.tutorialName = source.tutorialName; + this.students = source.getStudents().stream().map(JsonAdaptedPerson::new).collect(Collectors.toList()); + } + + public String getTutorialName() { + return tutorialName; + } + + public List getStudents() { + return new ArrayList<>(students); + } + + public TutorialClass toModelType() { + try { + ArrayList students = new ArrayList<>(); + for (JsonAdaptedPerson student : this.students) { + students.add(student.toModelType()); + } + return new TutorialClass(tutorialName, students); + } catch (IllegalValueException e) { + throw new IllegalArgumentException(e.getMessage()); + } + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof JsonAdaptedTutorialClass)) { + return false; + } + + JsonAdaptedTutorialClass otherTutorialClass = (JsonAdaptedTutorialClass) other; + return tutorialName.equals(otherTutorialClass.tutorialName) && students.equals(otherTutorialClass.students); + } +} diff --git a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java b/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java index 3b66418affb..38b00867ace 100644 --- a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java +++ b/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonCreator; @@ -74,4 +75,36 @@ public AddressBook toModelType() throws IllegalValueException { return addressBook; } + /** + * Adds a person to the students list of a specific tutorial class within a module. + * + * @param tutorialName The name of the tutorial class to which the person will be added. + * @param person The person to be added. + * @throws IllegalValueException if the tutorial class or module does not exist in the address book. + */ + public void addPersonToTutorialClass(String moduleName, String tutorialName, Person person) throws IllegalValueException { + // Find the module that contains the specified tutorial class + Optional moduleOptional = modules.stream() + .filter(moduleCode -> moduleCode.getModuleName().equals(moduleName)) + .findFirst(); + + if (moduleOptional.isPresent()) { + JsonAdaptedModule module = moduleOptional.get(); + // Find the tutorial class with the specified name + Optional tutorialOptional = module.getTutorialClasses().stream() + .filter(tutorial -> tutorial.getTutorialName().equals(tutorialName)) + .findFirst(); + + if (tutorialOptional.isPresent()) { + JsonAdaptedTutorialClass tutorialClass = tutorialOptional.get(); + // Add the person to the students list of the tutorial class + tutorialClass.getStudents().add(new JsonAdaptedPerson(person)); + } else { + throw new IllegalValueException("Tutorial class '" + tutorialName + "' not found in module."); + } + } else { + throw new IllegalValueException("Module containing tutorial class '" + tutorialName + "' not found."); + } + } + } diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/seedu/address/storage/StorageManager.java index d3bb8d385c9..92c39f56e67 100644 --- a/src/main/java/seedu/address/storage/StorageManager.java +++ b/src/main/java/seedu/address/storage/StorageManager.java @@ -21,7 +21,8 @@ public class StorageManager implements Storage { private UserPrefsStorage userPrefsStorage; /** - * Creates a {@code StorageManager} with the given {@code AddressBookStorage} and {@code UserPrefStorage}. + * Creates a {@code StorageManager} with the given {@code AddressBookStorage} + * and {@code UserPrefStorage}. */ public StorageManager(AddressBookStorage addressBookStorage, UserPrefsStorage userPrefsStorage) { this.addressBookStorage = addressBookStorage; @@ -45,7 +46,6 @@ public void saveUserPrefs(ReadOnlyUserPrefs userPrefs) throws IOException { userPrefsStorage.saveUserPrefs(userPrefs); } - // ================ AddressBook methods ============================== @Override diff --git a/src/test/java/seedu/address/logic/commands/AddCommandTest.java b/src/test/java/seedu/address/logic/commands/AddCommandTest.java index c72568729da..6d6d4579a69 100644 --- a/src/test/java/seedu/address/logic/commands/AddCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddCommandTest.java @@ -23,6 +23,7 @@ import seedu.address.model.ReadOnlyAddressBook; import seedu.address.model.ReadOnlyUserPrefs; import seedu.address.model.module.ModuleCode; +import seedu.address.model.module.TutorialClass; import seedu.address.model.person.Person; import seedu.address.testutil.PersonBuilder; @@ -139,6 +140,16 @@ public boolean hasPerson(Person person) { throw new AssertionError("This method should not be called."); } + @Override + public TutorialClass findTutorialClassFromList(TutorialClass tutorialClass, ModuleCode moduleCode) { + throw new AssertionError("This method should not be called."); + } + + @Override + public void addPersonToTutorialClass(Person person, ModuleCode moduleCode, TutorialClass tutorialClass) { + throw new AssertionError("This method should not be called."); + } + @Override public void deletePerson(Person target) { throw new AssertionError("This method should not be called."); diff --git a/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java b/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java index 17a474f0c25..9b0923731f0 100644 --- a/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java @@ -30,7 +30,9 @@ import seedu.address.model.module.ModuleCode; import seedu.address.model.module.TutorialClass; import seedu.address.model.person.Email; +import seedu.address.model.person.Person; import seedu.address.model.person.StudentId; +import seedu.address.testutil.PersonBuilder; /** * Contains integration tests (interaction with the Model) and unit tests for @@ -39,6 +41,7 @@ public class AddStudentToClassCommandTest { private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + private TutorialClass tutorialClass; @BeforeEach public void setUp() { @@ -46,6 +49,7 @@ public void setUp() { model.addModule(newModule); TutorialClass newTutorialClass = new TutorialClass(VALID_TUTORIAL_AMY); newModule.addTutorialClass(newTutorialClass); + tutorialClass = newTutorialClass; } @Test @@ -63,7 +67,7 @@ public void execute_invalidStudent_fail() { } - /* @Test + @Test public void execute_duplicateStudent_fail() { Person person = new PersonBuilder().build(); model.addPerson(person); @@ -77,7 +81,7 @@ public void execute_duplicateStudent_fail() { String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, person, tutorialClass)); assertCommandFailure(addStudentToClassByEmailCommand, model, String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, person, tutorialClass)); - } */ + } @Test public void equals() { diff --git a/src/test/java/seedu/address/storage/JsonAdaptedModuleTest.java b/src/test/java/seedu/address/storage/JsonAdaptedModuleTest.java index 6d8a011c43e..881159da6e7 100644 --- a/src/test/java/seedu/address/storage/JsonAdaptedModuleTest.java +++ b/src/test/java/seedu/address/storage/JsonAdaptedModuleTest.java @@ -4,6 +4,7 @@ import static seedu.address.testutil.Assert.assertThrows; import java.util.ArrayList; +import java.util.stream.Collectors; import org.junit.jupiter.api.Test; @@ -24,7 +25,8 @@ void toModelType_success() throws Exception { @Test void toModelType_invalidModuleCode_throwsIllegalValueException() { - JsonAdaptedModule jsonModule = new JsonAdaptedModule(INVALID_MODULE, new ArrayList()); + JsonAdaptedModule jsonModule = new JsonAdaptedModule(INVALID_MODULE, new ArrayList().stream() + .map(JsonAdaptedTutorialClass::new).collect(Collectors.toCollection(ArrayList::new))); String expectedMessage = JsonAdaptedModule.MISSING_FIELD_MESSAGE_FORMAT; assertThrows(IllegalValueException.class, expectedMessage, jsonModule::toModelType); } From 01e480c7b6b26722466146bb669317a5bf7b8963 Mon Sep 17 00:00:00 2001 From: whelan-low Date: Wed, 20 Mar 2024 00:51:28 +0800 Subject: [PATCH 21/33] Add test case --- src/main/java/seedu/address/ui/MainWindow.java | 15 ++++++++++++--- .../java/seedu/address/ui/MainWindowTest.java | 17 +++++++++++++++++ .../java/seedu/address/ui/ModuleCardTest.java | 1 - 3 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 src/test/java/seedu/address/ui/MainWindowTest.java diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index 43c8a94480a..6ffedde3176 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -205,6 +205,17 @@ private void handleExit() { primaryStage.hide(); } + /** + * Returns true if the command requires module view and + * false if the command does not. + * + * @return true if command requires module view + */ + public static boolean useModuleView(String commandText) { + return commandText.equals(ListClassesCommand.COMMAND_WORD) + || commandText.split(" ")[0].equals(AddClassCommand.COMMAND_WORD) + || commandText.split(" ")[0].equals(DeleteClassCommand.COMMAND_WORD); + } public PersonListPanel getPersonListPanel() { return personListPanel; } @@ -230,9 +241,7 @@ private CommandResult executeCommand(String commandText) throws CommandException clearPanels(); - if (commandText.equals(ListClassesCommand.COMMAND_WORD) - || commandText.split(" ")[0].equals(AddClassCommand.COMMAND_WORD) - || commandText.split(" ")[0].equals(DeleteClassCommand.COMMAND_WORD)) { + if (useModuleView(commandText)) { switchToModuleListPanel(); } else { switchToPersonListPanel(); diff --git a/src/test/java/seedu/address/ui/MainWindowTest.java b/src/test/java/seedu/address/ui/MainWindowTest.java new file mode 100644 index 00000000000..bad032d960d --- /dev/null +++ b/src/test/java/seedu/address/ui/MainWindowTest.java @@ -0,0 +1,17 @@ +package seedu.address.ui; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; + +class MainWindowTest { + + @Test + void useModuleView() { + assertTrue(MainWindow.useModuleView("/list_classes")); + assertTrue(MainWindow.useModuleView("/add_class module/CS2103T tutorial/T09")); + assertTrue(MainWindow.useModuleView("/delete_class module/CS2103T tutorial/T09")); + assertFalse(MainWindow.useModuleView("/list_students")); + } +} diff --git a/src/test/java/seedu/address/ui/ModuleCardTest.java b/src/test/java/seedu/address/ui/ModuleCardTest.java index 2aaa1accfa2..719798319e6 100644 --- a/src/test/java/seedu/address/ui/ModuleCardTest.java +++ b/src/test/java/seedu/address/ui/ModuleCardTest.java @@ -6,7 +6,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.condition.OS; - import javafx.embed.swing.JFXPanel; import seedu.address.model.module.ModuleCode; From 60e651daa76194b3b59a4352eef1243cd468608b Mon Sep 17 00:00:00 2001 From: whelan-low Date: Wed, 20 Mar 2024 00:54:46 +0800 Subject: [PATCH 22/33] Fix Checkstyle --- src/test/java/seedu/address/ui/MainWindowTest.java | 6 +++--- src/test/java/seedu/address/ui/ModuleCardTest.java | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/test/java/seedu/address/ui/MainWindowTest.java b/src/test/java/seedu/address/ui/MainWindowTest.java index bad032d960d..f9b60892088 100644 --- a/src/test/java/seedu/address/ui/MainWindowTest.java +++ b/src/test/java/seedu/address/ui/MainWindowTest.java @@ -1,9 +1,9 @@ package seedu.address.ui; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; class MainWindowTest { diff --git a/src/test/java/seedu/address/ui/ModuleCardTest.java b/src/test/java/seedu/address/ui/ModuleCardTest.java index 719798319e6..c5e9f1c1c23 100644 --- a/src/test/java/seedu/address/ui/ModuleCardTest.java +++ b/src/test/java/seedu/address/ui/ModuleCardTest.java @@ -6,7 +6,9 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.condition.OS; + import javafx.embed.swing.JFXPanel; + import seedu.address.model.module.ModuleCode; public class ModuleCardTest { From 1f8eef3b5e6d5794c35bbba1fde3bc573acac399 Mon Sep 17 00:00:00 2001 From: whelan-low Date: Wed, 20 Mar 2024 00:58:09 +0800 Subject: [PATCH 23/33] Fix checkstyle --- src/test/java/seedu/address/ui/ModuleCardTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/seedu/address/ui/ModuleCardTest.java b/src/test/java/seedu/address/ui/ModuleCardTest.java index c5e9f1c1c23..2aaa1accfa2 100644 --- a/src/test/java/seedu/address/ui/ModuleCardTest.java +++ b/src/test/java/seedu/address/ui/ModuleCardTest.java @@ -8,7 +8,6 @@ import org.junit.jupiter.api.condition.OS; import javafx.embed.swing.JFXPanel; - import seedu.address.model.module.ModuleCode; public class ModuleCardTest { From 11e41236d37796f5b0716e8709682ba2c24f6cbb Mon Sep 17 00:00:00 2001 From: Jajared Date: Wed, 20 Mar 2024 01:08:01 +0800 Subject: [PATCH 24/33] Update backend logic --- .../AddStudentToClassByEmailCommand.java | 14 +++--- .../AddStudentToClassByIdCommand.java | 11 ++-- .../AddStudentToClassByIndexCommand.java | 7 ++- .../AddStudentToClassCommandParser.java | 1 - .../java/seedu/address/model/AddressBook.java | 50 +++++++++++++------ .../seedu/address/model/ModelManager.java | 7 ++- .../address/model/module/TutorialClass.java | 37 +++++++------- .../storage/JsonAdaptedTutorialClass.java | 24 +++++++-- .../storage/JsonSerializableAddressBook.java | 26 ++++++---- .../AddStudentToClassCommandTest.java | 10 ++-- 10 files changed, 119 insertions(+), 68 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java index 711813b0bf2..9cd6aadc887 100644 --- a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByEmailCommand.java @@ -27,7 +27,6 @@ public class AddStudentToClassByEmailCommand extends AddStudentToClassCommand { /** * Adds a student to a class by email. - * * @param email * @param module * @param tutorialClass @@ -50,20 +49,21 @@ public CommandResult execute(Model model) throws CommandException { if (personToAdd == null) { throw new CommandException(String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, email)); } - System.out.println(tutorialClass.getStudents()); if (tutorialClass.hasStudent(personToAdd)) { throw new CommandException( - String.format(TutorialClassMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, personToAdd, - tutorialClass)); + String.format(TutorialClassMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, + Messages.format(personToAdd), tutorialClass)); } else { - model.addPersonToTutorialClass(personToAdd, module, tutorialClass); + model.addPersonToTutorialClass(personToAdd, module, tutorialClass); return new CommandResult( String.format(TutorialClassMessages.MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS, - Messages.format(personToAdd), module, - tutorialClass)); + Messages.format(personToAdd), module, tutorialClass)); } } + /** + * Returns true if both AddStudentToClassByEmailCommand have the same email. + */ @Override public boolean equals(Object other) { if (other == this) { diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java index 7f1ee4b252f..b02b3ec6c7b 100644 --- a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIdCommand.java @@ -45,18 +45,21 @@ public CommandResult execute(Model model) throws CommandException { Person personToAdd; personToAdd = model.searchPersonByPredicate(predicate); if (personToAdd == null) { - throw new CommandException(String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, studentId)); + throw new CommandException(String.format(PersonMessages.MESSAGE_PERSON_STUDENT_ID_NOT_FOUND, studentId)); } if (tutorialClass.hasStudent(personToAdd)) { - throw new CommandException(String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, personToAdd, - tutorialClass)); + throw new CommandException(String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, + Messages.format(personToAdd), tutorialClass)); } else { - model.addPersonToTutorialClass(personToAdd, module, tutorialClass); + model.addPersonToTutorialClass(personToAdd, module, tutorialClass); return new CommandResult(String.format(PersonMessages.MESSAGE_ADD_STUDENT_TO_CLASS_SUCCESS, Messages.format(personToAdd), module, tutorialClass)); } } + /** + * Returns true if both AddStudentToClassByIdCommand have the same studentId. + */ @Override public boolean equals(Object other) { if (other == this) { diff --git a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java index ed589c380d9..283be417bdd 100644 --- a/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java +++ b/src/main/java/seedu/address/logic/commands/addstudenttoclasscommands/AddStudentToClassByIndexCommand.java @@ -46,8 +46,8 @@ public CommandResult execute(Model model) throws CommandException { } if (tutorialClass.hasStudent(personToAdd)) { - throw new CommandException(String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, personToAdd, - tutorialClass)); + throw new CommandException(String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, + Messages.format(personToAdd), tutorialClass)); } else { model.addPersonToTutorialClass(personToAdd, module, tutorialClass); return new CommandResult( @@ -56,6 +56,9 @@ public CommandResult execute(Model model) throws CommandException { } } + /** + * Returns true if both AddStudentToClassByIndexCommand have the same index. + */ @Override public boolean equals(Object other) { if (other == this) { diff --git a/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java b/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java index 7841097f1e1..20c7f5e4985 100644 --- a/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddStudentToClassCommandParser.java @@ -29,7 +29,6 @@ public class AddStudentToClassCommandParser implements Parser modules; /* - * The 'unusual' code block below is a non-static initialization block, sometimes used to avoid duplication - * between constructors. See https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html + * The 'unusual' code block below is a non-static initialization block, + * sometimes used to avoid duplication + * between constructors. See + * https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html * - * Note that non-static init blocks are not recommended to use. There are other ways to avoid duplication - * among constructors. + * Note that non-static init blocks are not recommended to use. There are other + * ways to avoid duplication + * among constructors. */ { persons = new UniquePersonList(); modules = new ArrayList<>(); } - public AddressBook() {} + public AddressBook() { + } /** * Creates an AddressBook using the Persons in the {@code toBeCopied} @@ -53,6 +59,7 @@ public AddressBook(ReadOnlyAddressBook toBeCopied) { public void setPersons(List persons) { this.persons.setPersons(persons); } + /** * Replaces the contents of the module list with {@code modules}. */ @@ -75,7 +82,8 @@ public void resetData(ReadOnlyAddressBook newData) { //// person-level operations /** - * Returns true if a person with the same identity as {@code person} exists in the address book. + * Returns true if a person with the same identity as {@code person} exists in + * the address book. */ public boolean hasPerson(Person person) { requireNonNull(person); @@ -91,7 +99,8 @@ public void addPerson(Person p) { } /** - * Returns true if a module with the same identity as {@code module} exists in the address book. + * Returns true if a module with the same identity as {@code module} exists in + * the address book. */ @Override public boolean hasModule(ModuleCode module) { @@ -118,19 +127,25 @@ public ModuleCode findModuleFromList(ModuleCode module) { /** * Returns the tutorial object from the tutorial list if it exists. */ - public TutorialClass findTutorialClassFromList(TutorialClass tutorialClass, ModuleCode moduleCode) { + public TutorialClass findTutorialClassFromList(TutorialClass tutorialClass, ModuleCode moduleCode) + throws CommandException { requireNonNull(tutorialClass); requireNonNull(moduleCode); ModuleCode moduleInList = findModuleFromList(moduleCode); if (moduleInList == null) { - throw new IllegalArgumentException("Module does not exist in the address book."); + throw new CommandException(String.format(ModuleMessages.MESSAGE_MODULE_NOT_FOUND, moduleCode)); } - return moduleInList.getTutorialClasses().stream() + TutorialClass tutorialClassInList = moduleInList.getTutorialClasses().stream() .filter(tutorial -> tutorial.equals(tutorialClass)) .findFirst() .orElse(null); + if (tutorialClassInList == null) { + throw new CommandException(String.format(ModuleMessages.MESSAGE_TUTORIAL_DOES_NOT_BELONG_TO_MODULE, + tutorialClass, moduleCode)); + } + return tutorialClassInList; } - + /** * Adds a module to the address book. * The module must not already exist in the address book. (TODO) @@ -141,7 +156,8 @@ public void addModule(ModuleCode m) { } /** - * Adds a person to the students list of a specific tutorial class within a module. + * Adds a person to the students list of a specific tutorial class within a + * module. */ public void addPersonToTutorialClass(Person person, ModuleCode module, TutorialClass tutorialClass) { requireNonNull(person); @@ -160,9 +176,11 @@ public void addPersonToTutorialClass(Person person, ModuleCode module, TutorialC } /** - * Replaces the given person {@code target} in the list with {@code editedPerson}. + * Replaces the given person {@code target} in the list with + * {@code editedPerson}. * {@code target} must exist in the address book. - * The person identity of {@code editedPerson} must not be the same as another existing person in the address book. + * The person identity of {@code editedPerson} must not be the same as another + * existing person in the address book. */ public void setPerson(Person target, Person editedPerson) { requireNonNull(editedPerson); @@ -183,8 +201,8 @@ public void removePerson(Person key) { @Override public String toString() { return new ToStringBuilder(this) - .add("persons", persons) - .toString(); + .add("persons", persons) + .toString(); } @Override diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index 612c55f7a1b..0d4068d58b2 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -105,8 +105,11 @@ public ModuleCode findModuleFromList(ModuleCode module) { @Override public TutorialClass findTutorialClassFromList(TutorialClass tutorialClass, ModuleCode moduleCode) { - requireAllNonNull(tutorialClass, moduleCode); - return addressBook.findTutorialClassFromList(tutorialClass, moduleCode); + try { + return addressBook.findTutorialClassFromList(tutorialClass, moduleCode); + } catch (Exception e) { + return null; + } } @Override diff --git a/src/main/java/seedu/address/model/module/TutorialClass.java b/src/main/java/seedu/address/model/module/TutorialClass.java index 11a078da380..26bd331005a 100644 --- a/src/main/java/seedu/address/model/module/TutorialClass.java +++ b/src/main/java/seedu/address/model/module/TutorialClass.java @@ -25,28 +25,21 @@ public class TutorialClass { public final String tutorialName; private final ArrayList students; + /** * Constructs a {@code TutorialClass} with default values. - * Initializes the {@code value} field to an empty string and creates an empty list for {@code students}. + * Initializes the {@code value} field to an empty string and creates an empty + * list for {@code students}. */ public TutorialClass() { this.tutorialName = ""; this.students = new ArrayList<>(); } - /** - * Set students to the tutorial class - * @param students - */ - public void setStudents(ArrayList students) { - this.students.addAll(students); - } - - /** * A constructor for TutorialClass. Creates an empty tutorial class with no * students. - * @param name of tutorial to be added + * @param tutorialClass to be added */ public TutorialClass(String tutorialClass) { requireAllNonNull(tutorialClass); @@ -56,10 +49,9 @@ public TutorialClass(String tutorialClass) { } /** - * A constructor for TutorialClass. Creates a tutorial with the list of students - * specified. - * @param name of tutorial to be added - * @param students to be in the added tutorial + * A constructor for TutorialClass. Creates a tutorial class with students. + * @param tutorialClass to be added + * @param students in the tutorial class */ public TutorialClass(String tutorialClass, ArrayList students) { requireAllNonNull(tutorialClass); @@ -67,23 +59,32 @@ public TutorialClass(String tutorialClass, ArrayList students) { this.tutorialName = tutorialClass; this.students = students; } + + /** + * Set students to the tutorial class. + * @param students + */ + public void setStudents(ArrayList students) { + this.students.addAll(students); + } + /** * Returns true if a given string is a valid tutorial class code. */ public static boolean isValidTutorialClass(String test) { return test.matches(VALIDATION_REGEX); } + /** * Retrieves the tutorial class. - * * @return The tutorial class. */ public TutorialClass getTutorialClass() { return this; } + /** * Retrieves the list of students in the tutorial class. - * * @return The list of students in the tutorial class. */ public ArrayList getStudents() { @@ -123,7 +124,7 @@ public boolean equals(Object other) { } TutorialClass otherTutorialClass = (TutorialClass) other; - return tutorialName.equals(otherTutorialClass.tutorialName) && students.equals(otherTutorialClass.students); + return tutorialName.equals(otherTutorialClass.tutorialName); } @Override diff --git a/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java b/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java index 444427ef70b..62e0913348c 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java @@ -1,21 +1,29 @@ package seedu.address.storage; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; import seedu.address.commons.exceptions.IllegalValueException; import seedu.address.model.module.TutorialClass; import seedu.address.model.person.Person; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; +/** + * Jackson-friendly version of {@link TutorialClass}. + */ public class JsonAdaptedTutorialClass { private final String tutorialName; private final List students; + /** + * Constructs a {@code JsonAdaptedTutorialClass} with the given {@code tutorialName}. + */ @JsonCreator public JsonAdaptedTutorialClass(@JsonProperty("tutorialName") String tutorialName, @JsonProperty("students") List students) { @@ -23,19 +31,29 @@ public JsonAdaptedTutorialClass(@JsonProperty("tutorialName") String tutorialNam this.students = students != null ? new ArrayList<>(students) : new ArrayList<>(); } + /** + * Converts a given {@code TutorialClass} into this class for Jackson use. + */ public JsonAdaptedTutorialClass(TutorialClass source) { this.tutorialName = source.tutorialName; this.students = source.getStudents().stream().map(JsonAdaptedPerson::new).collect(Collectors.toList()); } + @JsonValue public String getTutorialName() { return tutorialName; } + @JsonValue public List getStudents() { return new ArrayList<>(students); } + /** + * Converts this Jackson-friendly adapted tutorial class object into the model's {@code TutorialClass} object. + * + * @throws IllegalValueException if there were any data constraints violated in the adapted tutorial class. + */ public TutorialClass toModelType() { try { ArrayList students = new ArrayList<>(); diff --git a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java b/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java index ce5809ffc42..4befbd2cb15 100644 --- a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java +++ b/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java @@ -28,11 +28,12 @@ class JsonSerializableAddressBook { private final List modules = new ArrayList<>(); /** - * Constructs a {@code JsonSerializableAddressBook} with the given persons and modules. + * Constructs a {@code JsonSerializableAddressBook} with the given persons and + * modules. */ @JsonCreator public JsonSerializableAddressBook(@JsonProperty("persons") List persons, - @JsonProperty("modules") List modules) { + @JsonProperty("modules") List modules) { if (persons != null) { this.persons.addAll(persons); } @@ -44,7 +45,8 @@ public JsonSerializableAddressBook(@JsonProperty("persons") List moduleOptional = modules.stream() .filter(moduleCode -> moduleCode.getModuleName().equals(moduleName)) diff --git a/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java b/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java index 9b0923731f0..844198357ac 100644 --- a/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java @@ -20,6 +20,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import seedu.address.logic.Messages; import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByEmailCommand; import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByIdCommand; import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByIndexCommand; @@ -63,10 +64,9 @@ public void execute_invalidStudent_fail() { assertCommandFailure(addStudentToClassByEmailCommand, model, String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, INVALID_EMAIL)); assertCommandFailure(addStudentToClassByIdCommand, model, - String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, INVALID_STUDENT_ID)); + String.format(PersonMessages.MESSAGE_PERSON_STUDENT_ID_NOT_FOUND, INVALID_STUDENT_ID)); } - @Test public void execute_duplicateStudent_fail() { Person person = new PersonBuilder().build(); @@ -78,9 +78,11 @@ public void execute_duplicateStudent_fail() { person.getStudentId(), new ModuleCode(VALID_MODULE_AMY), new TutorialClass(VALID_TUTORIAL_AMY)); assertCommandFailure(addStudentToClassByIdCommand, model, - String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, person, tutorialClass)); + String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, Messages.format(person), + tutorialClass)); assertCommandFailure(addStudentToClassByEmailCommand, model, - String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, person, tutorialClass)); + String.format(PersonMessages.MESSAGE_DUPLICATE_STUDENT_IN_CLASS, Messages.format(person), + tutorialClass)); } @Test From 6b77c54e733ec17b13a532250c3f01b7e5cba437 Mon Sep 17 00:00:00 2001 From: whelan-low Date: Wed, 20 Mar 2024 01:11:35 +0800 Subject: [PATCH 25/33] Fix method --- src/main/java/seedu/address/ui/MainWindow.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index 6ffedde3176..c5c1a39ef3d 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -212,9 +212,10 @@ private void handleExit() { * @return true if command requires module view */ public static boolean useModuleView(String commandText) { - return commandText.equals(ListClassesCommand.COMMAND_WORD) + boolean result = commandText.equals(ListClassesCommand.COMMAND_WORD) || commandText.split(" ")[0].equals(AddClassCommand.COMMAND_WORD) || commandText.split(" ")[0].equals(DeleteClassCommand.COMMAND_WORD); + return result; } public PersonListPanel getPersonListPanel() { return personListPanel; From 45dec849359fd9f0fa2b87d9df46e52e04233d76 Mon Sep 17 00:00:00 2001 From: whelan-low Date: Wed, 20 Mar 2024 01:26:40 +0800 Subject: [PATCH 26/33] Fix dependency issue --- build.gradle | 3 +++ src/main/java/seedu/address/ui/MainWindow.java | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 997495b6ade..528e722d8a4 100644 --- a/build.gradle +++ b/build.gradle @@ -57,6 +57,9 @@ dependencies { implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'win' implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'mac' implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-swing', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-swing', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-swing', version: javaFxVersion, classifier: 'linux' implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.7.0' implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.7.4' diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index c5c1a39ef3d..a154644fe40 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -212,10 +212,10 @@ private void handleExit() { * @return true if command requires module view */ public static boolean useModuleView(String commandText) { - boolean result = commandText.equals(ListClassesCommand.COMMAND_WORD) - || commandText.split(" ")[0].equals(AddClassCommand.COMMAND_WORD) - || commandText.split(" ")[0].equals(DeleteClassCommand.COMMAND_WORD); - return result; + String commandWord = commandText.split(" ")[0]; + return commandWord.equals(ListClassesCommand.COMMAND_WORD) + || commandWord.equals(AddClassCommand.COMMAND_WORD) + || commandWord.equals(DeleteClassCommand.COMMAND_WORD); } public PersonListPanel getPersonListPanel() { return personListPanel; From bc427b8e1a317e4eeac9d6a1e73a3aaf661cde2c Mon Sep 17 00:00:00 2001 From: Jajared Date: Wed, 20 Mar 2024 01:53:46 +0800 Subject: [PATCH 27/33] Added json tests --- .../java/seedu/address/model/AddressBook.java | 2 +- .../storage/JsonAdaptedTutorialClass.java | 4 +- .../AddStudentToClassCommandTest.java | 19 +++++---- .../logic/commands/CommandTestUtil.java | 4 +- .../storage/JsonAdaptedTutorialClassTest.java | 40 +++++++++++++++++++ .../JsonSerializableAddressBookTest.java | 3 +- 6 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 src/test/java/seedu/address/storage/JsonAdaptedTutorialClassTest.java diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index 7d519a3905b..b8eb17e3ff6 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -128,7 +128,7 @@ public ModuleCode findModuleFromList(ModuleCode module) { * Returns the tutorial object from the tutorial list if it exists. */ public TutorialClass findTutorialClassFromList(TutorialClass tutorialClass, ModuleCode moduleCode) - throws CommandException { + throws CommandException { requireNonNull(tutorialClass); requireNonNull(moduleCode); ModuleCode moduleInList = findModuleFromList(moduleCode); diff --git a/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java b/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java index 62e0913348c..562b3c5dc7a 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java @@ -54,7 +54,7 @@ public List getStudents() { * * @throws IllegalValueException if there were any data constraints violated in the adapted tutorial class. */ - public TutorialClass toModelType() { + public TutorialClass toModelType() throws IllegalValueException { try { ArrayList students = new ArrayList<>(); for (JsonAdaptedPerson student : this.students) { @@ -62,7 +62,7 @@ public TutorialClass toModelType() { } return new TutorialClass(tutorialName, students); } catch (IllegalValueException e) { - throw new IllegalArgumentException(e.getMessage()); + throw new IllegalValueException(TutorialClass.MESSAGE_CONSTRAINTS); } } diff --git a/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java b/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java index 844198357ac..99b26f87727 100644 --- a/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddStudentToClassCommandTest.java @@ -2,8 +2,8 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.logic.commands.CommandTestUtil.INVALID_EMAIL; -import static seedu.address.logic.commands.CommandTestUtil.INVALID_STUDENT_ID; +import static seedu.address.logic.commands.CommandTestUtil.INVALID_PERSON_EMAIL; +import static seedu.address.logic.commands.CommandTestUtil.INVALID_PERSON_STUDENT_ID; import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY; import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB; import static seedu.address.logic.commands.CommandTestUtil.VALID_MODULE_AMY; @@ -20,6 +20,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import seedu.address.commons.core.index.Index; import seedu.address.logic.Messages; import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByEmailCommand; import seedu.address.logic.commands.addstudenttoclasscommands.AddStudentToClassByIdCommand; @@ -56,15 +57,19 @@ public void setUp() { @Test public void execute_invalidStudent_fail() { AddStudentToClassByEmailCommand addStudentToClassByEmailCommand = new AddStudentToClassByEmailCommand( - new Email(INVALID_EMAIL), new ModuleCode(VALID_MODULE_AMY), new TutorialClass(VALID_TUTORIAL_AMY)); + new Email(INVALID_PERSON_EMAIL), new ModuleCode(VALID_MODULE_AMY), + new TutorialClass(VALID_TUTORIAL_AMY)); AddStudentToClassByIdCommand addStudentToClassByIdCommand = new AddStudentToClassByIdCommand( - new StudentId(INVALID_STUDENT_ID), new ModuleCode(VALID_MODULE_AMY), + new StudentId(INVALID_PERSON_STUDENT_ID), new ModuleCode(VALID_MODULE_AMY), new TutorialClass(VALID_TUTORIAL_AMY)); - + AddStudentToClassByIndexCommand addStudentToClassByIndexCommand = new AddStudentToClassByIndexCommand( + Index.fromOneBased(1000), new ModuleCode(VALID_MODULE_AMY), new TutorialClass(VALID_TUTORIAL_AMY)); assertCommandFailure(addStudentToClassByEmailCommand, model, - String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, INVALID_EMAIL)); + String.format(PersonMessages.MESSAGE_PERSON_EMAIL_NOT_FOUND, INVALID_PERSON_EMAIL)); assertCommandFailure(addStudentToClassByIdCommand, model, - String.format(PersonMessages.MESSAGE_PERSON_STUDENT_ID_NOT_FOUND, INVALID_STUDENT_ID)); + String.format(PersonMessages.MESSAGE_PERSON_STUDENT_ID_NOT_FOUND, INVALID_PERSON_STUDENT_ID)); + assertCommandFailure(addStudentToClassByIndexCommand, model, + String.format(PersonMessages.MESSAGE_PERSON_INDEX_NOT_FOUND, 1000)); } @Test diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java index cd9ac9bcb05..1113a6212ae 100644 --- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java +++ b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java @@ -58,8 +58,8 @@ public class CommandTestUtil { public static final String TAG_DESC_FRIEND = " " + PREFIX_TAG + VALID_TAG_FRIEND; public static final String TAG_DESC_HUSBAND = " " + PREFIX_TAG + VALID_TAG_HUSBAND; - public static final String INVALID_EMAIL = "test@example.com"; - public static final String INVALID_STUDENT_ID = "A2222222A"; + public static final String INVALID_PERSON_EMAIL = "test@example.com"; + public static final String INVALID_PERSON_STUDENT_ID = "A2222222A"; // '&' not allowed in names public static final String INVALID_NAME_DESC = " " + PREFIX_NAME + "James&"; diff --git a/src/test/java/seedu/address/storage/JsonAdaptedTutorialClassTest.java b/src/test/java/seedu/address/storage/JsonAdaptedTutorialClassTest.java new file mode 100644 index 00000000000..950583ef283 --- /dev/null +++ b/src/test/java/seedu/address/storage/JsonAdaptedTutorialClassTest.java @@ -0,0 +1,40 @@ +package seedu.address.storage; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static seedu.address.testutil.Assert.assertThrows; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; + +import seedu.address.model.module.TutorialClass; +import seedu.address.testutil.PersonBuilder; + +class JsonAdaptedTutorialClassTest { + + private static final String VALID_TUTORIAL_NAME = "T01"; + private static final String INVALID_TUTORIAL_NAME = ""; + private static final List VALID_STUDENTS_LIST = new ArrayList<>( + Arrays.asList(new PersonBuilder().build(), new PersonBuilder().build())).stream() + .map(JsonAdaptedPerson::new) + .collect(Collectors.toList()); + + @Test + void toModelType_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_STUDENTS_LIST); + String expectedMessage = TutorialClass.MESSAGE_CONSTRAINTS; + assertThrows(IllegalArgumentException.class, expectedMessage, jsonTutorialClass::toModelType); + } + +} diff --git a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java b/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java index f93c54f3416..42898e1287a 100644 --- a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java +++ b/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java @@ -23,7 +23,7 @@ public class JsonSerializableAddressBookTest { private static final Path TYPICAL_PERSONS_FILE = TEST_DATA_FOLDER.resolve("typicalPersonsAddressBook.json"); private static final Path INVALID_PERSON_FILE = TEST_DATA_FOLDER.resolve("invalidPersonAddressBook.json"); private static final Path DUPLICATE_PERSON_FILE = TEST_DATA_FOLDER.resolve("duplicatePersonAddressBook.json"); - private static final Path TYPICAL_MODULES_FILE = TEST_DATA_FOLDER.resolve("typicalModulesAddressBook.json"); + private static final Path TYPICAL_MODULES_FILE = TEST_DATA_FOLDER.resolve("typicalModuleAddressBook.json"); @Test public void toModelType_typicalPersonsFile_success() throws Exception { @@ -62,4 +62,5 @@ public void toModelType_duplicateModules_throwsIllegalValueException() { JsonSerializableAddressBook data = new JsonSerializableAddressBook(new ArrayList<>(), modules); assertThrows(IllegalValueException.class, data::toModelType); } + } From 32721085828e59503cf07b020f56d536a40ef55c Mon Sep 17 00:00:00 2001 From: Jajared Date: Wed, 20 Mar 2024 02:06:20 +0800 Subject: [PATCH 28/33] Fix save bug --- .../java/seedu/address/storage/JsonAdaptedTutorialClass.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java b/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java index 562b3c5dc7a..2829c30ef25 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java @@ -38,13 +38,11 @@ public JsonAdaptedTutorialClass(TutorialClass source) { this.tutorialName = source.tutorialName; this.students = source.getStudents().stream().map(JsonAdaptedPerson::new).collect(Collectors.toList()); } - - @JsonValue + public String getTutorialName() { return tutorialName; } - @JsonValue public List getStudents() { return new ArrayList<>(students); } From c3eb64d2c3b0ce286e1214698acfa3346a5ef1b7 Mon Sep 17 00:00:00 2001 From: Jajared Date: Wed, 20 Mar 2024 02:08:06 +0800 Subject: [PATCH 29/33] Remove unused import --- .../address/storage/JsonAdaptedTutorialClass.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java b/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java index 2829c30ef25..ea2e6d597cc 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedTutorialClass.java @@ -6,13 +6,11 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonValue; import seedu.address.commons.exceptions.IllegalValueException; import seedu.address.model.module.TutorialClass; import seedu.address.model.person.Person; - /** * Jackson-friendly version of {@link TutorialClass}. */ @@ -22,7 +20,8 @@ public class JsonAdaptedTutorialClass { private final List students; /** - * Constructs a {@code JsonAdaptedTutorialClass} with the given {@code tutorialName}. + * Constructs a {@code JsonAdaptedTutorialClass} with the given + * {@code tutorialName}. */ @JsonCreator public JsonAdaptedTutorialClass(@JsonProperty("tutorialName") String tutorialName, @@ -38,7 +37,7 @@ public JsonAdaptedTutorialClass(TutorialClass source) { this.tutorialName = source.tutorialName; this.students = source.getStudents().stream().map(JsonAdaptedPerson::new).collect(Collectors.toList()); } - + public String getTutorialName() { return tutorialName; } @@ -48,9 +47,11 @@ public List getStudents() { } /** - * Converts this Jackson-friendly adapted tutorial class object into the model's {@code TutorialClass} object. + * Converts this Jackson-friendly adapted tutorial class object into the model's + * {@code TutorialClass} object. * - * @throws IllegalValueException if there were any data constraints violated in the adapted tutorial class. + * @throws IllegalValueException if there were any data constraints violated in + * the adapted tutorial class. */ public TutorialClass toModelType() throws IllegalValueException { try { From c858148e9b77316d457f3a58454106668c57488d Mon Sep 17 00:00:00 2001 From: Zack-Tay <101039486+Zack-Tay@users.noreply.github.com> Date: Wed, 20 Mar 2024 02:10:14 +0800 Subject: [PATCH 30/33] Update isSamePerson definition to include email value check (#85) * Email is now a unique field that would "determine" if a Person is the same person. * Ensures that if user specifies the same email as an existing student in the list, the system will throw a duplicate error. --- .../java/seedu/address/model/person/Person.java | 12 +++++++++--- src/main/resources/view/PersonListCard.fxml | 4 ---- .../java/seedu/address/model/person/PersonTest.java | 13 +++++++++---- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java index 12a4abda8cf..2980b1672d0 100644 --- a/src/main/java/seedu/address/model/person/Person.java +++ b/src/main/java/seedu/address/model/person/Person.java @@ -52,7 +52,7 @@ public Set getTags() { } /** - * Returns true if both persons have the same StudentId. + * Returns true if both persons have the same StudentId or email. * This defines a weaker notion of equality between two persons. */ public boolean isSamePerson(Person otherPerson) { @@ -60,8 +60,14 @@ public boolean isSamePerson(Person otherPerson) { return true; } - return otherPerson != null - && otherPerson.getStudentId().equals(getStudentId()); + if (otherPerson == null) { + return false; + } + + boolean checkSameStudentId = otherPerson.getStudentId().equals(getStudentId()); + boolean checkSameEmail = otherPerson.getEmail().equals(getEmail()); + + return otherPerson != null && (checkSameStudentId || checkSameEmail); } /** diff --git a/src/main/resources/view/PersonListCard.fxml b/src/main/resources/view/PersonListCard.fxml index 41a8dbb31f8..c4f76673f0d 100644 --- a/src/main/resources/view/PersonListCard.fxml +++ b/src/main/resources/view/PersonListCard.fxml @@ -30,10 +30,6 @@