diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index f24ff3a2c0c9..65811c0dd425 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -170,32 +170,41 @@ Medeina will return `john` and `John Doe` * Type in `find Betsy Tim John` + Medeina will return any person having names `Betsy`, `Tim`, or `John` -=== Deleting a contact, pet patient or appointment : `delete` or `d` +=== Deleting a owner, pet patient or appointment : `delete` or `d` `[Since v1.3]` Use the following command format to: -Delete an existing contact:: `delete **-o** INDEX` +Delete an existing owner:: `delete **-o** INDEX` +Forcefully deleting an existing owner:: `delete **-fo** INDEX` Delete an existing pet patient:: `delete **-p** INDEX` +Forcefully deleting an existing pet patient:: `delete **-fp** INDEX` Delete an existing appointment:: `delete **-a** INDEX` **** * The command deletes the contact, pet patient or appointment at the specified `INDEX`. +* The commands -o and -p will not run if there are dependencies that rely on it. To forcefully delete, use the -fo and -fp options. +* Upon a forceful delete of an owner, all appointments and pet patients binded to the owner are automatically deleted as well. +* Upon a forceful delete of a pet patient, all appointments binded to the pet patient are automatically deleted as well. * The index refers to the index number shown in the most recent listing, provided by the `list` command. **** [IMPORTANT] ==== -The index *must be a positive integer* `1, 2, 3, ...` +The index *must be a positive integer* and should not be *invalid* `1, 2, 3, ...` ==== Examples: * Type in `list -o` + -`delete 2` + -Medeina will deletes the 2nd contact in Medeina's address book. +`delete -o 2` + +Medeina will deletes the 2nd owner in Medeina's address book only if there are no pet patients and appointments binded to that owner. + +* Type in `list -o` + +`delete -fo 2` + +Medeina will deletes the 2nd owner in Medeina's address book, and all pet patients and appointments binded to that owner * Type in `find -o Betsy` + -`d 1` + +`d -o 1` + Medeina will delete the 1st contact in the results of the `find` command. === Selecting a contact : `select` or `s` diff --git a/src/main/java/seedu/address/MainApp.java b/src/main/java/seedu/address/MainApp.java index c3a0aacadca4..d8b9d0a4e688 100644 --- a/src/main/java/seedu/address/MainApp.java +++ b/src/main/java/seedu/address/MainApp.java @@ -41,7 +41,7 @@ */ public class MainApp extends Application { - public static final Version VERSION = new Version(0, 6, 0, true); + public static final Version VERSION = new Version(1, 3, 17, true); private static final Logger logger = LogsCenter.getLogger(MainApp.class); diff --git a/src/main/java/seedu/address/commons/core/Messages.java b/src/main/java/seedu/address/commons/core/Messages.java index 5d08eff58dfe..396be5a7eab6 100644 --- a/src/main/java/seedu/address/commons/core/Messages.java +++ b/src/main/java/seedu/address/commons/core/Messages.java @@ -7,10 +7,13 @@ public class Messages { public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command"; public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; + public static final String MESSAGE_INVALID_DISPLAYED_INDEX = "The index provided is invalid"; + public static final String MESSAGE_DEPENDENCIES_EXIST = "Relevant dependencies still exist!"; public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; public static final String MESSAGE_INVALID_PET_PATIENT_DISPLAYED_INDEX = "The pet patient index " + "provided is invalid"; public static final String MESSAGE_INVALID_APPOINTMENT_DISPLAYED_INDEX = "The appointment index " + "provided is invalid"; + public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; } diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java index 0cd0fbd860ad..e65e63a63064 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteCommand.java @@ -8,11 +8,17 @@ import seedu.address.commons.core.Messages; import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.appointment.Appointment; +import seedu.address.model.appointment.exceptions.AppointmentDependencyNotEmptyException; +import seedu.address.model.appointment.exceptions.AppointmentNotFoundException; import seedu.address.model.person.Person; import seedu.address.model.person.exceptions.PersonNotFoundException; +import seedu.address.model.petpatient.PetPatient; +import seedu.address.model.petpatient.exceptions.PetDependencyNotEmptyException; +import seedu.address.model.petpatient.exceptions.PetPatientNotFoundException; /** - * Deletes a person identified using it's last displayed index from the address book. + * Deletes a person, pet patient or appointment from the address book. */ public class DeleteCommand extends UndoableCommand { @@ -20,25 +26,86 @@ public class DeleteCommand extends UndoableCommand { public static final String COMMAND_ALIAS = "d"; public static final String MESSAGE_USAGE = COMMAND_WORD + + " -[f]o/-[f]p/-a" + + ": Deletes the person/pet/appointment identified by the index number used in the last listing.\n" + + "Additional -[f] options indicates forcefully deleting object and all related dependencies.\n" + + "Parameters: INDEX (must be a positive integer, must not be invalid)\n" + + "Example: " + COMMAND_WORD + " -o 1"; + + public static final String MESSAGE_USAGE_OWNER = COMMAND_WORD + + " -o" + ": Deletes the person identified by the index number used in the last person listing.\n" + + "Parameters: INDEX (must be a positive integer, must not be invalid)\n" + + "Example: " + COMMAND_WORD + " -o 1"; + + public static final String MESSAGE_USAGE_PET_PATIENT = COMMAND_WORD + + " -p" + + ": Deletes the pet patient identified by the index number used in the last pet patient listing.\n" + + "Parameters: INDEX (must be a positive integer, must not be invalid)\n" + + "Example: " + COMMAND_WORD + " -p 1"; + + public static final String MESSAGE_USAGE_APPOINTMENT = COMMAND_WORD + + " -a" + + ": Deletes the appointment identified by the index number used in the last appointment listing.\n" + + "Parameters: INDEX (must be a positive integer, must not be invalid)\n" + + "Example: " + COMMAND_WORD + " -a 1"; + + public static final String MESSAGE_USAGE_FORCE_OWNER = COMMAND_WORD + + " -fo" + + ": Forcefully deletes the person and all related dependencies " + + "identified by the index number used in the last person listing.\n" + "Parameters: INDEX (must be a positive integer)\n" - + "Example: " + COMMAND_WORD + " 1"; + + "Example: " + COMMAND_WORD + " -fo 1"; + + public static final String MESSAGE_USAGE_FORCE_PET_PATIENT = COMMAND_WORD + + " -fp" + + ": Forcefully deletes the pet and all related dependencies " + + "identified by the index number used in the last person listing.\n" + + "Parameters: INDEX (must be a positive integer, must not be invalid)\n" + + "Example: " + COMMAND_WORD + " -fp 1"; public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s"; + public static final String MESSAGE_DELETE_PET_PATIENT_SUCCESS = "Deleted Pet Patient: %1$s"; + public static final String MESSAGE_DELETE_APPOINTMENT_SUCCESS = "Deleted Appointment: %1$s"; private final Index targetIndex; + private final int type; private Person personToDelete; + private PetPatient petPatientToDelete; + private Appointment appointmentToDelete; - public DeleteCommand(Index targetIndex) { + public DeleteCommand(int type, Index targetIndex) { + this.type = type; this.targetIndex = targetIndex; } @Override - public CommandResult executeUndoableCommand() { - requireNonNull(personToDelete); + public CommandResult executeUndoableCommand() throws CommandException { + requireNonNull(model); + try { + switch (type) { + case 1: return deletePerson(); + case 2: return deletePetPatient(); + case 3: return deleteAppointment(); + case 4: return deleteForcePerson(); + case 5: return deleteForcePetPatient(); + default: + throw new CommandException(MESSAGE_USAGE); + } + } catch (PetDependencyNotEmptyException e) { + throw new CommandException(Messages.MESSAGE_DEPENDENCIES_EXIST); + } catch (AppointmentDependencyNotEmptyException e) { + throw new CommandException(Messages.MESSAGE_DEPENDENCIES_EXIST); + } + } + /** + * Deletes {@code personToDelete} from the address book. + */ + private CommandResult deletePerson() throws PetDependencyNotEmptyException { try { + requireNonNull(personToDelete); model.deletePerson(personToDelete); } catch (PersonNotFoundException pnfe) { throw new AssertionError("The target person cannot be missing"); @@ -47,17 +114,121 @@ public CommandResult executeUndoableCommand() { return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, personToDelete)); } - @Override - protected void preprocessUndoableCommand() throws CommandException { + private void getPersonToDelete() throws CommandException { List lastShownList = model.getFilteredPersonList(); if (targetIndex.getZeroBased() >= lastShownList.size()) { - throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + throw new CommandException(Messages.MESSAGE_INVALID_DISPLAYED_INDEX); } personToDelete = lastShownList.get(targetIndex.getZeroBased()); } + /** + * Deletes the pet patient {@code petPatientToDelete} from the address book. + */ + private CommandResult deletePetPatient() throws AppointmentDependencyNotEmptyException { + try { + requireNonNull(petPatientToDelete); + model.deletePetPatient(petPatientToDelete); + } catch (PetPatientNotFoundException ppnfe) { + throw new AssertionError("The target pet cannot be missing"); + } + + return new CommandResult(String.format(MESSAGE_DELETE_PET_PATIENT_SUCCESS, petPatientToDelete)); + } + + private void getPetPatientToDelete() throws CommandException { + List lastShownList = model.getFilteredPetPatientList(); + + if (targetIndex.getZeroBased() >= lastShownList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_DISPLAYED_INDEX); + } + + petPatientToDelete = lastShownList.get(targetIndex.getZeroBased()); + } + /** + * Deletes the appointment {@code appointmentToDelete} from the address book. + */ + private CommandResult deleteAppointment() { + try { + requireNonNull(appointmentToDelete); + model.deleteAppointment(appointmentToDelete); + } catch (AppointmentNotFoundException anfe) { + throw new AssertionError("The target appointment cannot be missing"); + } + + return new CommandResult(String.format(MESSAGE_DELETE_APPOINTMENT_SUCCESS, appointmentToDelete)); + } + + private void getAppointmentToDelete() throws CommandException { + List lastShownList = model.getFilteredAppointmentList(); + + if (targetIndex.getZeroBased() >= lastShownList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_DISPLAYED_INDEX); + } + + appointmentToDelete = lastShownList.get(targetIndex.getZeroBased()); + } + + /** + * Forcefully deletes {@code personToDelete} from the address book. + * All related dependencies (pet patients, appointments) will be deleted as well. + */ + private CommandResult deleteForcePerson() { + try { + requireNonNull(personToDelete); + model.deleteForcePerson(personToDelete); + } catch (PersonNotFoundException pnfe) { + throw new AssertionError("The target person cannot be missing"); + } catch (AppointmentNotFoundException anfe) { + throw new AssertionError("The relevant appointments cannot be missing"); + } catch (PetPatientNotFoundException ppnfe) { + throw new AssertionError("The relevant pet patients cannot be missing"); + } + + return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, personToDelete)); + } + + /** + * Forcefully deletes {@code petPatientToDelete} from the address book. + * All related dependencies (appointments) will be deleted as well. + */ + private CommandResult deleteForcePetPatient() { + try { + requireNonNull(petPatientToDelete); + model.deleteForcePetPatient(petPatientToDelete); + } catch (PetPatientNotFoundException ppnfe) { + throw new AssertionError("The target pet cannot be missing"); + } catch (AppointmentNotFoundException anfe) { + throw new AssertionError("The relevant appointments cannot be missing"); + } + + return new CommandResult(String.format(MESSAGE_DELETE_PET_PATIENT_SUCCESS, petPatientToDelete)); + } + + @Override + protected void preprocessUndoableCommand() throws CommandException { + try { + switch (type) { + case 1: getPersonToDelete(); + break; + case 2: getPetPatientToDelete(); + break; + case 3: getAppointmentToDelete(); + break; + case 4: getPersonToDelete(); + break; + case 5: getPetPatientToDelete(); + break; + default: + throw new CommandException(MESSAGE_USAGE); + } + } catch (CommandException e) { + throw new CommandException(Messages.MESSAGE_INVALID_DISPLAYED_INDEX); + } + } + @Override public boolean equals(Object other) { return other == this // short circuit if same object diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index fe340a09ca17..3dbcb8083732 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -196,6 +196,7 @@ protected void preprocessUndoableCommandForPerson() throws CommandException { if (index.getZeroBased() >= lastShownPersonList.size()) { throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + } personToEdit = lastShownPersonList.get(index.getZeroBased()); diff --git a/src/main/java/seedu/address/logic/commands/SelectCommand.java b/src/main/java/seedu/address/logic/commands/SelectCommand.java index 0bc2e3e21485..ac9e2103f859 100644 --- a/src/main/java/seedu/address/logic/commands/SelectCommand.java +++ b/src/main/java/seedu/address/logic/commands/SelectCommand.java @@ -36,7 +36,7 @@ public CommandResult execute() throws CommandException { List lastShownList = model.getFilteredPersonList(); if (targetIndex.getZeroBased() >= lastShownList.size()) { - throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + throw new CommandException(Messages.MESSAGE_INVALID_DISPLAYED_INDEX); } EventsCenter.getInstance().post(new JumpToListRequestEvent(targetIndex)); diff --git a/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java index fe9c1653850e..b2b955fc3280 100644 --- a/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java @@ -2,6 +2,9 @@ import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import seedu.address.commons.core.index.Index; import seedu.address.commons.exceptions.IllegalValueException; import seedu.address.logic.commands.DeleteCommand; @@ -12,19 +15,80 @@ */ public class DeleteCommandParser implements Parser { + private static final Pattern DELETE_COMMAND_FORMAT_OWNER = Pattern.compile("-(o)+(?.*)"); + private static final Pattern DELETE_COMMAND_FORMAT_PET_PATIENT = Pattern.compile("-(p)+(?.*)"); + private static final Pattern DELETE_COMMAND_FORMAT_APPOINTMENT = Pattern.compile("-(a)+(?.*)"); + private static final Pattern DELETE_COMMAND_FORMAT_FORCE_OWNER = Pattern.compile("-(fo)+(?.*)"); + private static final Pattern DELETE_COMMAND_FORMAT_FORCE_PET_PATIENT = Pattern.compile("-(fp)+(?.*)"); /** * Parses the given {@code String} of arguments in the context of the DeleteCommand * and returns an DeleteCommand object for execution. + * type changes depending on what pattern it matches * @throws ParseException if the user input does not conform the expected format */ public DeleteCommand parse(String args) throws ParseException { - try { - Index index = ParserUtil.parseIndex(args); - return new DeleteCommand(index); - } catch (IllegalValueException ive) { - throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE)); + String trimmedArgs = args.trim(); + + final Matcher matcherForOwner = DELETE_COMMAND_FORMAT_OWNER.matcher(trimmedArgs); + if (matcherForOwner.matches()) { + try { + int type = 1; + Index index = ParserUtil.parseIndex(matcherForOwner.group("index")); + return new DeleteCommand(type, index); + } catch (IllegalValueException ive) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE_OWNER)); + } + } + + final Matcher matcherForPetPatient = DELETE_COMMAND_FORMAT_PET_PATIENT.matcher(trimmedArgs); + if (matcherForPetPatient.matches()) { + try { + int type = 2; + Index index = ParserUtil.parseIndex(matcherForPetPatient.group("index")); + return new DeleteCommand(type, index); + } catch (IllegalValueException ive) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE_PET_PATIENT)); + } + } + + final Matcher matcherForAppointment = DELETE_COMMAND_FORMAT_APPOINTMENT.matcher(trimmedArgs); + if (matcherForAppointment.matches()) { + try { + int type = 3; + Index index = ParserUtil.parseIndex(matcherForAppointment.group("index")); + return new DeleteCommand(type, index); + } catch (IllegalValueException ive) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE_APPOINTMENT)); + } + } + + final Matcher matcherForForceOwner = DELETE_COMMAND_FORMAT_FORCE_OWNER.matcher(trimmedArgs); + if (matcherForForceOwner.matches()) { + try { + int type = 4; + Index index = ParserUtil.parseIndex(matcherForForceOwner.group("index")); + return new DeleteCommand(type, index); + } catch (IllegalValueException ive) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE_FORCE_OWNER)); + } } - } + final Matcher matcherForForcePetPatient = DELETE_COMMAND_FORMAT_FORCE_PET_PATIENT.matcher(trimmedArgs); + if (matcherForForcePetPatient.matches()) { + try { + int type = 5; + Index index = ParserUtil.parseIndex(matcherForForcePetPatient.group("index")); + return new DeleteCommand(type, index); + } catch (IllegalValueException ive) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE_FORCE_PET_PATIENT)); + } + } + + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE)); + } } diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index 93019ee5840b..5115433f0e91 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -2,8 +2,10 @@ import static java.util.Objects.requireNonNull; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -13,6 +15,8 @@ import javafx.collections.ObservableList; import seedu.address.model.appointment.Appointment; import seedu.address.model.appointment.UniqueAppointmentList; +import seedu.address.model.appointment.exceptions.AppointmentDependencyNotEmptyException; +import seedu.address.model.appointment.exceptions.AppointmentNotFoundException; import seedu.address.model.appointment.exceptions.DuplicateAppointmentException; import seedu.address.model.person.Person; import seedu.address.model.person.UniquePersonList; @@ -22,6 +26,8 @@ import seedu.address.model.petpatient.PetPatient; import seedu.address.model.petpatient.UniquePetPatientList; import seedu.address.model.petpatient.exceptions.DuplicatePetPatientException; +import seedu.address.model.petpatient.exceptions.PetDependencyNotEmptyException; +import seedu.address.model.petpatient.exceptions.PetPatientNotFoundException; import seedu.address.model.tag.Tag; import seedu.address.model.tag.UniqueTagList; @@ -171,6 +177,36 @@ public void addAppointment(Appointment a) throws DuplicateAppointmentException { appointments.add(appointment); } + /** + * Removes appointment {@code key} from this {@code AddressBook}. + * + * @throws AppointmentNotFoundException if the {@code key} is not in this {@code AddressBook}. + */ + public boolean removeAppointment(Appointment key) throws AppointmentNotFoundException { + if (appointments.remove(key)) { + removeUselessTags(); + return true; + } else { + throw new AppointmentNotFoundException(); + } + } + + /** + * Removes all appointments of pet patient {@code key} from this {@code AddressBook}. + */ + private void removeAllAppointments(PetPatient key) { + Iterator appointmentIterator = appointments.iterator(); + + while (appointmentIterator.hasNext()) { + Appointment appointment = appointmentIterator.next(); + + if (appointment.getPetPatientName().equals(key.getName()) + && appointment.getOwnerNric().equals(key.getOwner())) { + appointmentIterator.remove(); + } + } + } + /** * Removes all {@code tag}s not used by anyone in this {@code AddressBook}. * Reused from https://github.com/se-edu/addressbook-level4/pull/790/files with minor modifications @@ -182,6 +218,21 @@ private void removeUselessTags() { .map(Person::getTags) .flatMap(Set::stream) .collect(Collectors.toSet()); + Set appointmentTags = + appointments.asObservableList() + .stream() + .map(Appointment::getAppointmentTags) + .flatMap(Set::stream) + .collect(Collectors.toSet()); + Set petPatientTags = + petPatients.asObservableList() + .stream() + .map(PetPatient::getTags) + .flatMap(Set::stream) + .collect(Collectors.toSet()); + + personTags.addAll(appointmentTags); + personTags.addAll(petPatientTags); tags.setTags(personTags); } @@ -265,9 +316,44 @@ private Appointment syncWithAppointmentMasterTagList(Appointment appointment) { * Removes {@code key} from this {@code AddressBook}. * * @throws PersonNotFoundException if the {@code key} is not in this {@code AddressBook}. + * @throws PetDependencyNotEmptyException if the {@code key} still contains pet patients it is tied to. */ - public boolean removePerson(Person key) throws PersonNotFoundException { + public boolean removePerson(Person key) throws PersonNotFoundException, PetDependencyNotEmptyException { + for (PetPatient petPatient : petPatients) { + if (petPatient.getOwner().equals(key.getNric())) { + throw new PetDependencyNotEmptyException(); + } + } + if (persons.remove(key)) { + removeUselessTags(); + return true; + } else { + throw new PersonNotFoundException(); + } + } + + /** + * Forcefully removes {@code key} and all dependencies from this {@code AddressBook}. + * + * @throws PersonNotFoundException if the {@code key} is not in this {@code AddressBook}. + */ + public boolean removeForcePerson(Person key) throws PersonNotFoundException { + List petPatientArrayList = new ArrayList<>(); + for (PetPatient petPatient : petPatients) { + if (petPatient.getOwner().equals(key.getNric())) { + petPatientArrayList.add(petPatient); + } + } + + for (PetPatient petPatient : petPatientArrayList) { + removeAllAppointments(petPatient); + } + + removeAllPetPatient(key); + + if (persons.remove(key)) { + removeUselessTags(); return true; } else { throw new PersonNotFoundException(); @@ -288,6 +374,70 @@ public void addPetPatient(PetPatient p) throws DuplicatePetPatientException { petPatients.add(petPatient); } + /** + * Removes pet patient {@code key} from this {@code AddressBook}. + * + * @throws PetPatientNotFoundException if the {@code key} is not in this {@code AddressBook}. + * @throws AppointmentDependencyNotEmptyException if the {@code key} still contains appointments it is tied to. + */ + public boolean removePetPatient(PetPatient key) + throws PetPatientNotFoundException, AppointmentDependencyNotEmptyException { + for (Appointment appointment : appointments) { + if (appointment.getPetPatientName().equals(key.getName()) + && appointment.getOwnerNric().equals(key.getOwner())) { + throw new AppointmentDependencyNotEmptyException(); + } + } + + if (petPatients.remove(key)) { + removeUselessTags(); + return true; + } else { + throw new PetPatientNotFoundException(); + } + } + + /** + * Removes all pet patients belonging to {@code key} from this {@code AddressBook}. + */ + private void removeAllPetPatient(Person key) { + Iterator petPatientIterator = petPatients.iterator(); + + while (petPatientIterator.hasNext()) { + PetPatient petPatient = petPatientIterator.next(); + + if (petPatient.getOwner().equals(key.getNric())) { + petPatientIterator.remove(); + } + } + } + + /** + * Forcefully removes pet patient {@code key} from this {@code AddressBook}. + * + * @throws PetPatientNotFoundException if the {@code key} is not in this {@code AddressBook}. + */ + public boolean removeForcePetPatient(PetPatient key) + throws PetPatientNotFoundException { + Iterator appointmentIterator = appointments.iterator(); + + while (appointmentIterator.hasNext()) { + Appointment appointment = appointmentIterator.next(); + + if (appointment.getPetPatientName().equals(key.getName()) + && appointment.getOwnerNric().equals(key.getOwner())) { + appointmentIterator.remove(); + } + } + + if (petPatients.remove(key)) { + removeUselessTags(); + return true; + } else { + throw new PetPatientNotFoundException(); + } + } + //// tag-level operations public void addTag(Tag t) throws UniqueTagList.DuplicateTagException { diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index 54fd8dbebd79..1dbb644240ad 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -4,6 +4,8 @@ import javafx.collections.ObservableList; import seedu.address.model.appointment.Appointment; +import seedu.address.model.appointment.exceptions.AppointmentDependencyNotEmptyException; +import seedu.address.model.appointment.exceptions.AppointmentNotFoundException; import seedu.address.model.appointment.exceptions.DuplicateAppointmentException; import seedu.address.model.person.Person; import seedu.address.model.person.exceptions.DuplicateNricException; @@ -11,6 +13,8 @@ import seedu.address.model.person.exceptions.PersonNotFoundException; import seedu.address.model.petpatient.PetPatient; import seedu.address.model.petpatient.exceptions.DuplicatePetPatientException; +import seedu.address.model.petpatient.exceptions.PetDependencyNotEmptyException; +import seedu.address.model.petpatient.exceptions.PetPatientNotFoundException; import seedu.address.model.tag.Tag; /** @@ -29,7 +33,11 @@ public interface Model { ReadOnlyAddressBook getAddressBook(); /** Deletes the given person. */ - void deletePerson(Person target) throws PersonNotFoundException; + void deletePerson(Person target) throws PersonNotFoundException, PetDependencyNotEmptyException; + + /** Forcefully deletes the given person. */ + void deleteForcePerson(Person target) + throws PersonNotFoundException, PetPatientNotFoundException, AppointmentNotFoundException; /** Adds the given person */ void addPerson(Person person) throws DuplicatePersonException, DuplicateNricException; @@ -50,6 +58,9 @@ void updatePerson(Person target, Person editedPerson) /** Adds the given appointment */ void addAppointment(Appointment appointment) throws DuplicateAppointmentException; + /** Deletes the given appointment. */ + void deleteAppointment(Appointment target) throws AppointmentNotFoundException; + /** Returns an unmodifiable view of the filtered person list */ ObservableList getFilteredPersonList(); @@ -75,4 +86,10 @@ void updatePerson(Person target, Person editedPerson) void addPetPatient(PetPatient petPatient) throws DuplicatePetPatientException; + /** Deletes the given pet. */ + void deletePetPatient(PetPatient target) + throws PetPatientNotFoundException, AppointmentDependencyNotEmptyException; + + /** Forcefully deletes the given pet. */ + void deleteForcePetPatient(PetPatient target) throws PetPatientNotFoundException, AppointmentNotFoundException; } diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index 9d0b3a9208c5..a8d45b51ac71 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -13,6 +13,8 @@ import seedu.address.commons.core.LogsCenter; import seedu.address.commons.events.model.AddressBookChangedEvent; import seedu.address.model.appointment.Appointment; +import seedu.address.model.appointment.exceptions.AppointmentDependencyNotEmptyException; +import seedu.address.model.appointment.exceptions.AppointmentNotFoundException; import seedu.address.model.appointment.exceptions.DuplicateAppointmentException; import seedu.address.model.person.Person; import seedu.address.model.person.exceptions.DuplicateNricException; @@ -20,6 +22,8 @@ import seedu.address.model.person.exceptions.PersonNotFoundException; import seedu.address.model.petpatient.PetPatient; import seedu.address.model.petpatient.exceptions.DuplicatePetPatientException; +import seedu.address.model.petpatient.exceptions.PetDependencyNotEmptyException; +import seedu.address.model.petpatient.exceptions.PetPatientNotFoundException; import seedu.address.model.tag.Tag; /** @@ -70,11 +74,19 @@ private void indicateAddressBookChanged() { } @Override - public synchronized void deletePerson(Person target) throws PersonNotFoundException { + public synchronized void deletePerson(Person target) + throws PersonNotFoundException, PetDependencyNotEmptyException { addressBook.removePerson(target); indicateAddressBookChanged(); } + @Override + public synchronized void deleteForcePerson(Person target) + throws PersonNotFoundException { + addressBook.removeForcePerson(target); + indicateAddressBookChanged(); + } + @Override public synchronized void addPerson(Person person) throws DuplicatePersonException, DuplicateNricException { addressBook.addPerson(person); @@ -82,6 +94,20 @@ public synchronized void addPerson(Person person) throws DuplicatePersonExceptio indicateAddressBookChanged(); } + @Override + public synchronized void deletePetPatient(PetPatient target) + throws PetPatientNotFoundException, AppointmentDependencyNotEmptyException { + addressBook.removePetPatient(target); + indicateAddressBookChanged(); + } + + @Override + public synchronized void deleteForcePetPatient(PetPatient target) + throws PetPatientNotFoundException { + addressBook.removeForcePetPatient(target); + indicateAddressBookChanged(); + } + @Override public synchronized void addPetPatient(PetPatient petPatient) throws DuplicatePetPatientException { addressBook.addPetPatient(petPatient); @@ -98,6 +124,12 @@ public void updatePerson(Person target, Person editedPerson) indicateAddressBookChanged(); } + @Override + public synchronized void deleteAppointment(Appointment target) throws AppointmentNotFoundException { + addressBook.removeAppointment(target); + indicateAddressBookChanged(); + } + @Override public synchronized void addAppointment(Appointment appointment) throws DuplicateAppointmentException { addressBook.addAppointment(appointment); diff --git a/src/main/java/seedu/address/model/appointment/UniqueAppointmentList.java b/src/main/java/seedu/address/model/appointment/UniqueAppointmentList.java index ff00c45b205a..846781f911b3 100644 --- a/src/main/java/seedu/address/model/appointment/UniqueAppointmentList.java +++ b/src/main/java/seedu/address/model/appointment/UniqueAppointmentList.java @@ -66,6 +66,20 @@ public void setAppointment(Appointment target, Appointment editedAppointment) internalList.set(index, editedAppointment); } + /** + * Removes the equivalent pet patient from the list. + * + * @throws AppointmentNotFoundException if no such pet patient could be found in the list. + */ + public boolean remove(Appointment toRemove) throws AppointmentNotFoundException { + requireNonNull(toRemove); + final boolean appointmentFoundAndDeleted = internalList.remove(toRemove); + if (!appointmentFoundAndDeleted) { + throw new AppointmentNotFoundException(); + } + return appointmentFoundAndDeleted; + } + public void setAppointments(UniqueAppointmentList replacement) { this.internalList.setAll(replacement.internalList); } diff --git a/src/main/java/seedu/address/model/appointment/exceptions/AppointmentDependencyNotEmptyException.java b/src/main/java/seedu/address/model/appointment/exceptions/AppointmentDependencyNotEmptyException.java new file mode 100644 index 000000000000..48267cdd138c --- /dev/null +++ b/src/main/java/seedu/address/model/appointment/exceptions/AppointmentDependencyNotEmptyException.java @@ -0,0 +1,8 @@ +package seedu.address.model.appointment.exceptions; + +/** + * Signals that the operation is unable to continue because there are still appointments dependent. + */ + +public class AppointmentDependencyNotEmptyException extends Exception { +} diff --git a/src/main/java/seedu/address/model/petpatient/exceptions/PetDependencyNotEmptyException.java b/src/main/java/seedu/address/model/petpatient/exceptions/PetDependencyNotEmptyException.java new file mode 100644 index 000000000000..80bf41e69ecf --- /dev/null +++ b/src/main/java/seedu/address/model/petpatient/exceptions/PetDependencyNotEmptyException.java @@ -0,0 +1,7 @@ +package seedu.address.model.petpatient.exceptions; + +/** + * Signals that the operation is unable to continue because there are still pets dependent. + */ +public class PetDependencyNotEmptyException extends Exception { +} diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/address/logic/LogicManagerTest.java index 954c1fb04388..f94a2b674c87 100644 --- a/src/test/java/seedu/address/logic/LogicManagerTest.java +++ b/src/test/java/seedu/address/logic/LogicManagerTest.java @@ -1,7 +1,7 @@ package seedu.address.logic; import static org.junit.Assert.assertEquals; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX; +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_DISPLAYED_INDEX; import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND; import org.junit.Rule; @@ -34,8 +34,8 @@ public void execute_invalidCommandFormat_throwsParseException() { @Test public void execute_commandExecutionError_throwsCommandException() { - String deleteCommand = "delete 9"; - assertCommandException(deleteCommand, MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + String deleteCommand = "delete -o 9"; + assertCommandException(deleteCommand, MESSAGE_INVALID_DISPLAYED_INDEX); assertHistoryCorrect(deleteCommand); } diff --git a/src/test/java/seedu/address/logic/commands/AddCommandTest.java b/src/test/java/seedu/address/logic/commands/AddCommandTest.java index f53084f2f955..28311ab4ade6 100644 --- a/src/test/java/seedu/address/logic/commands/AddCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddCommandTest.java @@ -25,7 +25,6 @@ import seedu.address.model.appointment.exceptions.DuplicateAppointmentException; import seedu.address.model.person.Person; import seedu.address.model.person.exceptions.DuplicatePersonException; -import seedu.address.model.person.exceptions.PersonNotFoundException; import seedu.address.model.petpatient.PetPatient; import seedu.address.model.petpatient.exceptions.DuplicatePetPatientException; import seedu.address.model.tag.Tag; @@ -111,11 +110,26 @@ public void addPetPatient(PetPatient petPatient) throws DuplicatePetPatientExcep fail("This method should not be called."); } + @Override + public void deletePetPatient(PetPatient target) { + fail("This method should not be called."); + } + + @Override + public void deleteForcePetPatient(PetPatient target) { + fail("This method should not be called."); + } + @Override public void addAppointment(Appointment appointment) throws DuplicateAppointmentException { fail("This method should not be called."); } + @Override + public void deleteAppointment(Appointment target) { + fail("This method should not be called."); + } + @Override public void resetData(ReadOnlyAddressBook newData) { fail("This method should not be called."); @@ -128,7 +142,12 @@ public ReadOnlyAddressBook getAddressBook() { } @Override - public void deletePerson(Person target) throws PersonNotFoundException { + public void deletePerson(Person target) { + fail("This method should not be called."); + } + + @Override + public void deleteForcePerson(Person target) { fail("This method should not be called."); } diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java index 82502269e326..68bc26a7513f 100644 --- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java +++ b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java @@ -30,6 +30,7 @@ import seedu.address.model.person.NameContainsKeywordsPredicate; import seedu.address.model.person.Person; import seedu.address.model.person.exceptions.PersonNotFoundException; +import seedu.address.model.petpatient.exceptions.PetDependencyNotEmptyException; import seedu.address.testutil.EditPersonDescriptorBuilder; /** @@ -200,6 +201,8 @@ public static void deleteFirstPerson(Model model) { model.deletePerson(firstPerson); } catch (PersonNotFoundException pnfe) { throw new AssertionError("Person in filtered list must exist in model.", pnfe); + } catch (PetDependencyNotEmptyException e) { + throw new AssertionError("Dependency still exists!"); } } diff --git a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java index 866e6a9be32a..64b0df083356 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java @@ -21,7 +21,11 @@ import seedu.address.model.Model; import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; +import seedu.address.model.appointment.Appointment; import seedu.address.model.person.Person; +import seedu.address.model.petpatient.PetPatient; +import seedu.address.testutil.TypicalAppointments; +import seedu.address.testutil.TypicalPetPatients; /** * Contains integration tests (interaction with the Model, UndoCommand and RedoCommand) and unit tests for @@ -32,9 +36,9 @@ public class DeleteCommandTest { private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); @Test - public void execute_validIndexUnfilteredList_success() throws Exception { + public void executeDeleteOwner_validIndexUnfilteredList_success() throws Exception { Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); - DeleteCommand deleteCommand = prepareCommand(INDEX_FIRST_PERSON); + DeleteCommand deleteCommand = prepareDeleteOwnerCommand(INDEX_FIRST_PERSON); String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, personToDelete); @@ -45,11 +49,105 @@ public void execute_validIndexUnfilteredList_success() throws Exception { } @Test - public void execute_invalidIndexUnfilteredList_throwsCommandException() throws Exception { + public void executeDeleteForceOwner_validIndexUnfilteredList_success() throws Exception { + model.addPetPatient(TypicalPetPatients.JOKER); + Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); + DeleteCommand deleteCommand = prepareDeleteForceOwnerCommand(INDEX_FIRST_PERSON); + + String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, personToDelete); + + ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + expectedModel.deletePerson(personToDelete); + + assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel); + } + + @Test + public void executeDeletePetPatient_validIndexUnfilteredList_success() throws Exception { + model.addPetPatient(TypicalPetPatients.JEWEL); + model.addPetPatient(TypicalPetPatients.JOKER); + PetPatient petPatientToDelete = model.getFilteredPetPatientList().get(INDEX_FIRST_PERSON.getZeroBased()); + DeleteCommand deleteCommand = prepareDeletePetPatientCommand(INDEX_FIRST_PERSON); + + String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PET_PATIENT_SUCCESS, petPatientToDelete); + + ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + expectedModel.deletePetPatient(petPatientToDelete); + + assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel); + } + + @Test + public void executeDeleteForcePetPatient_validIndexUnfilteredList_success() throws Exception { + model.addPetPatient(TypicalPetPatients.JEWEL); + model.addPetPatient(TypicalPetPatients.JOKER); + model.addAppointment(TypicalAppointments.BOB_APP); + PetPatient petPatientToDelete = model.getFilteredPetPatientList().get(INDEX_FIRST_PERSON.getZeroBased()); + DeleteCommand deleteCommand = prepareDeleteForcePetPatientCommand(INDEX_FIRST_PERSON); + + String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PET_PATIENT_SUCCESS, petPatientToDelete); + + ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + expectedModel.deletePetPatient(petPatientToDelete); + + assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel); + } + + @Test + public void executeDeleteAppointment_validIndexUnfilteredList_success() throws Exception { + model.addPetPatient(TypicalPetPatients.JEWEL); + model.addPetPatient(TypicalPetPatients.JOKER); + model.addAppointment(TypicalAppointments.ALICE_APP); + model.addAppointment(TypicalAppointments.BOB_APP); + Appointment appointmentToDelete = model.getFilteredAppointmentList().get(INDEX_FIRST_PERSON.getZeroBased()); + DeleteCommand deleteCommand = prepareDeleteAppointmentCommand(INDEX_FIRST_PERSON); + + String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_APPOINTMENT_SUCCESS, appointmentToDelete); + + ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + expectedModel.deleteAppointment(appointmentToDelete); + + assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel); + } + + @Test + public void executeDeleteOwner_invalidIndexUnfilteredList_throwsCommandException() throws Exception { + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); + DeleteCommand deleteCommand = prepareDeleteOwnerCommand(outOfBoundIndex); + + assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_DISPLAYED_INDEX); + } + + @Test + public void executeDeleteForceOwner_invalidIndexUnfilteredList_throwsCommandException() throws Exception { Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); - DeleteCommand deleteCommand = prepareCommand(outOfBoundIndex); + DeleteCommand deleteCommand = prepareDeleteForceOwnerCommand(outOfBoundIndex); - assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_DISPLAYED_INDEX); + } + + @Test + public void executeDeletePetPatient_invalidIndexUnfilteredList_throwsCommandException() throws Exception { + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPetPatientList().size() + 1); + DeleteCommand deleteCommand = prepareDeletePetPatientCommand(outOfBoundIndex); + + assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_DISPLAYED_INDEX); + } + + @Test + public void executeDeleteForcePetPatient_invalidIndexUnfilteredList_throwsCommandException() throws Exception { + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPetPatientList().size() + 1); + DeleteCommand deleteCommand = prepareDeleteForcePetPatientCommand(outOfBoundIndex); + + assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_DISPLAYED_INDEX); + } + + @Test + public void executeDeleteAppointment_invalidIndexUnfilteredList_throwsCommandException() throws Exception { + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredAppointmentList().size() + 1); + DeleteCommand deleteCommand = prepareDeleteAppointmentCommand(outOfBoundIndex); + + assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_DISPLAYED_INDEX); } @Test @@ -57,7 +155,7 @@ public void execute_validIndexFilteredList_success() throws Exception { showPersonAtIndex(model, INDEX_FIRST_PERSON); Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); - DeleteCommand deleteCommand = prepareCommand(INDEX_FIRST_PERSON); + DeleteCommand deleteCommand = prepareDeleteOwnerCommand(INDEX_FIRST_PERSON); String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, personToDelete); @@ -76,9 +174,9 @@ public void execute_invalidIndexFilteredList_throwsCommandException() { // ensures that outOfBoundIndex is still in bounds of address book list assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size()); - DeleteCommand deleteCommand = prepareCommand(outOfBoundIndex); + DeleteCommand deleteCommand = prepareDeleteOwnerCommand(outOfBoundIndex); - assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_DISPLAYED_INDEX); } @Test @@ -87,7 +185,7 @@ public void executeUndoRedo_validIndexUnfilteredList_success() throws Exception UndoCommand undoCommand = prepareUndoCommand(model, undoRedoStack); RedoCommand redoCommand = prepareRedoCommand(model, undoRedoStack); Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); - DeleteCommand deleteCommand = prepareCommand(INDEX_FIRST_PERSON); + DeleteCommand deleteCommand = prepareDeleteOwnerCommand(INDEX_FIRST_PERSON); Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); // delete -> first person deleted @@ -108,10 +206,10 @@ public void executeUndoRedo_invalidIndexUnfilteredList_failure() { UndoCommand undoCommand = prepareUndoCommand(model, undoRedoStack); RedoCommand redoCommand = prepareRedoCommand(model, undoRedoStack); Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); - DeleteCommand deleteCommand = prepareCommand(outOfBoundIndex); + DeleteCommand deleteCommand = prepareDeleteOwnerCommand(outOfBoundIndex); // execution failed -> deleteCommand not pushed into undoRedoStack - assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_DISPLAYED_INDEX); // no commands in undoRedoStack -> undoCommand and redoCommand fail assertCommandFailure(undoCommand, model, UndoCommand.MESSAGE_FAILURE); @@ -130,7 +228,7 @@ public void executeUndoRedo_validIndexFilteredList_samePersonDeleted() throws Ex UndoRedoStack undoRedoStack = new UndoRedoStack(); UndoCommand undoCommand = prepareUndoCommand(model, undoRedoStack); RedoCommand redoCommand = prepareRedoCommand(model, undoRedoStack); - DeleteCommand deleteCommand = prepareCommand(INDEX_FIRST_PERSON); + DeleteCommand deleteCommand = prepareDeleteOwnerCommand(INDEX_FIRST_PERSON); Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); showPersonAtIndex(model, INDEX_SECOND_PERSON); @@ -150,14 +248,14 @@ public void executeUndoRedo_validIndexFilteredList_samePersonDeleted() throws Ex @Test public void equals() throws Exception { - DeleteCommand deleteFirstCommand = prepareCommand(INDEX_FIRST_PERSON); - DeleteCommand deleteSecondCommand = prepareCommand(INDEX_SECOND_PERSON); + DeleteCommand deleteFirstCommand = prepareDeleteOwnerCommand(INDEX_FIRST_PERSON); + DeleteCommand deleteSecondCommand = prepareDeleteOwnerCommand(INDEX_SECOND_PERSON); // same object -> returns true assertTrue(deleteFirstCommand.equals(deleteFirstCommand)); // same values -> returns true - DeleteCommand deleteFirstCommandCopy = prepareCommand(INDEX_FIRST_PERSON); + DeleteCommand deleteFirstCommandCopy = prepareDeleteOwnerCommand(INDEX_FIRST_PERSON); assertTrue(deleteFirstCommand.equals(deleteFirstCommandCopy)); // one command preprocessed when previously equal -> returns false @@ -177,8 +275,44 @@ public void equals() throws Exception { /** * Returns a {@code DeleteCommand} with the parameter {@code index}. */ - private DeleteCommand prepareCommand(Index index) { - DeleteCommand deleteCommand = new DeleteCommand(index); + private DeleteCommand prepareDeleteOwnerCommand(Index index) { + DeleteCommand deleteCommand = new DeleteCommand(1, index); + deleteCommand.setData(model, new CommandHistory(), new UndoRedoStack()); + return deleteCommand; + } + + /** + * Returns a {@code DeleteCommand} with the parameter {@code index}. + */ + private DeleteCommand prepareDeleteForceOwnerCommand(Index index) { + DeleteCommand deleteCommand = new DeleteCommand(4, index); + deleteCommand.setData(model, new CommandHistory(), new UndoRedoStack()); + return deleteCommand; + } + + /** + * Returns a {@code DeleteCommand} with the parameter {@code index}. + */ + private DeleteCommand prepareDeletePetPatientCommand(Index index) { + DeleteCommand deleteCommand = new DeleteCommand(2, index); + deleteCommand.setData(model, new CommandHistory(), new UndoRedoStack()); + return deleteCommand; + } + + /** + * Returns a {@code DeleteCommand} with the parameter {@code index}. + */ + private DeleteCommand prepareDeleteForcePetPatientCommand(Index index) { + DeleteCommand deleteCommand = new DeleteCommand(5, index); + deleteCommand.setData(model, new CommandHistory(), new UndoRedoStack()); + return deleteCommand; + } + + /** + * Returns a {@code DeleteCommand} with the parameter {@code index}. + */ + private DeleteCommand prepareDeleteAppointmentCommand(Index index) { + DeleteCommand deleteCommand = new DeleteCommand(3, index); deleteCommand.setData(model, new CommandHistory(), new UndoRedoStack()); return deleteCommand; } diff --git a/src/test/java/seedu/address/logic/commands/RedoCommandTest.java b/src/test/java/seedu/address/logic/commands/RedoCommandTest.java index e615f089a4f2..7fa2f5c5524f 100644 --- a/src/test/java/seedu/address/logic/commands/RedoCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/RedoCommandTest.java @@ -25,8 +25,8 @@ public class RedoCommandTest { private static final UndoRedoStack EMPTY_STACK = new UndoRedoStack(); private final Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); - private final DeleteCommand deleteCommandOne = new DeleteCommand(INDEX_FIRST_PERSON); - private final DeleteCommand deleteCommandTwo = new DeleteCommand(INDEX_SECOND_PERSON); + private final DeleteCommand deleteCommandOne = new DeleteCommand(4, INDEX_FIRST_PERSON); + private final DeleteCommand deleteCommandTwo = new DeleteCommand(4, INDEX_SECOND_PERSON); @Before public void setUp() throws Exception { diff --git a/src/test/java/seedu/address/logic/commands/SelectCommandTest.java b/src/test/java/seedu/address/logic/commands/SelectCommandTest.java index 4840900602ac..9caf96583d7c 100644 --- a/src/test/java/seedu/address/logic/commands/SelectCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/SelectCommandTest.java @@ -52,7 +52,7 @@ public void execute_validIndexUnfilteredList_success() { public void execute_invalidIndexUnfilteredList_failure() { Index outOfBoundsIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); - assertExecutionFailure(outOfBoundsIndex, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertExecutionFailure(outOfBoundsIndex, Messages.MESSAGE_INVALID_DISPLAYED_INDEX); } @Test @@ -70,7 +70,7 @@ public void execute_invalidIndexFilteredList_failure() { // ensures that outOfBoundIndex is still in bounds of address book list assertTrue(outOfBoundsIndex.getZeroBased() < model.getAddressBook().getPersonList().size()); - assertExecutionFailure(outOfBoundsIndex, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertExecutionFailure(outOfBoundsIndex, Messages.MESSAGE_INVALID_DISPLAYED_INDEX); } @Test diff --git a/src/test/java/seedu/address/logic/commands/UndoCommandTest.java b/src/test/java/seedu/address/logic/commands/UndoCommandTest.java index 3eb5f2f18346..995d851b478a 100644 --- a/src/test/java/seedu/address/logic/commands/UndoCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/UndoCommandTest.java @@ -24,8 +24,8 @@ public class UndoCommandTest { private static final UndoRedoStack EMPTY_STACK = new UndoRedoStack(); private final Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); - private final DeleteCommand deleteCommandOne = new DeleteCommand(INDEX_FIRST_PERSON); - private final DeleteCommand deleteCommandTwo = new DeleteCommand(INDEX_FIRST_PERSON); + private final DeleteCommand deleteCommandOne = new DeleteCommand(4, INDEX_FIRST_PERSON); + private final DeleteCommand deleteCommandTwo = new DeleteCommand(4, INDEX_FIRST_PERSON); @Before public void setUp() { diff --git a/src/test/java/seedu/address/logic/commands/UndoableCommandTest.java b/src/test/java/seedu/address/logic/commands/UndoableCommandTest.java index 7d00a7471b86..0033e98d594d 100644 --- a/src/test/java/seedu/address/logic/commands/UndoableCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/UndoableCommandTest.java @@ -13,8 +13,10 @@ import seedu.address.model.Model; import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; +import seedu.address.model.appointment.exceptions.AppointmentNotFoundException; import seedu.address.model.person.Person; import seedu.address.model.person.exceptions.PersonNotFoundException; +import seedu.address.model.petpatient.exceptions.PetPatientNotFoundException; public class UndoableCommandTest { private final Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); @@ -58,9 +60,13 @@ class DummyCommand extends UndoableCommand { public CommandResult executeUndoableCommand() throws CommandException { Person personToDelete = model.getFilteredPersonList().get(0); try { - model.deletePerson(personToDelete); + model.deleteForcePerson(personToDelete); } catch (PersonNotFoundException pnfe) { fail("Impossible: personToDelete was retrieved from model."); + } catch (PetPatientNotFoundException e) { + fail("Impossible: personToDelete was retrieved from model."); + } catch (AppointmentNotFoundException e) { + fail("Impossible: personToDelete was retrieved from model."); } return new CommandResult(""); } diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 487a73a9a7c3..0d458403f097 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -71,17 +71,17 @@ public void parseCommand_clear() throws Exception { } @Test - public void parseCommand_deleteAlias() throws Exception { + public void parseCommand_deleteAlias_forcePerson() throws Exception { DeleteCommand command = (DeleteCommand) parser.parseCommand( - DeleteCommand.COMMAND_ALIAS + " " + INDEX_FIRST_PERSON.getOneBased()); - assertEquals(new DeleteCommand(INDEX_FIRST_PERSON), command); + DeleteCommand.COMMAND_ALIAS + " -fo " + INDEX_FIRST_PERSON.getOneBased()); + assertEquals(new DeleteCommand(4, INDEX_FIRST_PERSON), command); } @Test - public void parseCommand_delete() throws Exception { + public void parseCommand_delete_forcePerson() throws Exception { DeleteCommand command = (DeleteCommand) parser.parseCommand( - DeleteCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased()); - assertEquals(new DeleteCommand(INDEX_FIRST_PERSON), command); + DeleteCommand.COMMAND_WORD + " -fo " + INDEX_FIRST_PERSON.getOneBased()); + assertEquals(new DeleteCommand(4, INDEX_FIRST_PERSON), command); } @Test diff --git a/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java index 825732ced6ac..7759409ff6f4 100644 --- a/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java @@ -22,7 +22,7 @@ public class DeleteCommandParserTest { @Test public void parse_validArgs_returnsDeleteCommand() { - assertParseSuccess(parser, "1", new DeleteCommand(INDEX_FIRST_PERSON)); + assertParseSuccess(parser, "-fo 1", new DeleteCommand(4, INDEX_FIRST_PERSON)); } @Test diff --git a/src/test/java/seedu/address/model/AddressBookTest.java b/src/test/java/seedu/address/model/AddressBookTest.java index d1e72adb8429..4e3f94142910 100644 --- a/src/test/java/seedu/address/model/AddressBookTest.java +++ b/src/test/java/seedu/address/model/AddressBookTest.java @@ -4,7 +4,7 @@ import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND; import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_UNUSED; -import static seedu.address.testutil.TypicalAppointments.ALLY; +import static seedu.address.testutil.TypicalAppointments.ALICE_APP; import static seedu.address.testutil.TypicalPersons.ALICE; import static seedu.address.testutil.TypicalPersons.AMY; import static seedu.address.testutil.TypicalPersons.BOB; @@ -61,8 +61,8 @@ public void resetData_withDuplicatePersons_throwsAssertionError() { // Repeat ALICE twice List newPersons = Arrays.asList(ALICE, ALICE); List newTags = new ArrayList<>(ALICE.getTags()); - List newAppointments = Arrays.asList(ALLY); - List newAppointmentTags = new ArrayList<>(ALLY.getAppointmentTags()); + List newAppointments = Arrays.asList(ALICE_APP); + List newAppointmentTags = new ArrayList<>(ALICE_APP.getAppointmentTags()); AddressBookStub newData = new AddressBookStub(newPersons, newTags, newAppointments, newAppointmentTags); thrown.expect(AssertionError.class); diff --git a/src/test/java/seedu/address/model/ModelManagerTest.java b/src/test/java/seedu/address/model/ModelManagerTest.java index 435192651c1f..8bf1eaa5eb3b 100644 --- a/src/test/java/seedu/address/model/ModelManagerTest.java +++ b/src/test/java/seedu/address/model/ModelManagerTest.java @@ -34,6 +34,20 @@ public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException modelManager.getFilteredPersonList().remove(0); } + @Test + public void getFilteredPetPatientList_modifyList_throwsUnsupportedOperationException() { + ModelManager modelManager = new ModelManager(); + thrown.expect(UnsupportedOperationException.class); + modelManager.getFilteredPetPatientList().remove(0); + } + + @Test + public void getFilteredAppointmentList_modifyList_throwsUnsupportedOperationException() { + ModelManager modelManager = new ModelManager(); + thrown.expect(UnsupportedOperationException.class); + modelManager.getFilteredAppointmentList().remove(0); + } + // Reused from https://github.com/se-edu/addressbook-level4/pull/790/files with minor modifications @Test public void deleteUnusedTag_modelUnchanged() throws Exception { diff --git a/src/test/java/seedu/address/storage/XmlAdaptedAppointmentTest.java b/src/test/java/seedu/address/storage/XmlAdaptedAppointmentTest.java index f66cb1c42073..5953846e9f57 100644 --- a/src/test/java/seedu/address/storage/XmlAdaptedAppointmentTest.java +++ b/src/test/java/seedu/address/storage/XmlAdaptedAppointmentTest.java @@ -2,7 +2,7 @@ import static org.junit.Assert.assertEquals; import static seedu.address.storage.XmlAdaptedAppointment.MISSING_FIELD_MESSAGE_FORMAT; -import static seedu.address.testutil.TypicalAppointments.ALLY; +import static seedu.address.testutil.TypicalAppointments.ALICE_APP; import java.time.LocalDateTime; import java.util.ArrayList; @@ -26,18 +26,18 @@ public class XmlAdaptedAppointmentTest { private static final String INVALID_DATETIME = "MAAAY 2018 8PM"; private static final String INVALID_APPOINTMENT_TAG = "#checkup"; - private static final String VALID_OWNER_NRIC = ALLY.getOwnerNric().toString(); - private static final String VALID_PET_PATIENT_NAME = ALLY.getPetPatientName().toString(); - private static final String VALID_REMARK = ALLY.getRemark().toString(); - private static final String VALID_DATETIME = ALLY.getFormattedLocalDateTime(); - private static final List VALID_APPOINTMENT_TAGS = ALLY.getAppointmentTags().stream() + private static final String VALID_OWNER_NRIC = ALICE_APP.getOwnerNric().toString(); + private static final String VALID_PET_PATIENT_NAME = ALICE_APP.getPetPatientName().toString(); + private static final String VALID_REMARK = ALICE_APP.getRemark().toString(); + private static final String VALID_DATETIME = ALICE_APP.getFormattedLocalDateTime(); + private static final List VALID_APPOINTMENT_TAGS = ALICE_APP.getAppointmentTags().stream() .map(XmlAdaptedTag::new) .collect(Collectors.toList()); @Test public void toModelType_validAppointmentDetails_returnsAppointment() throws Exception { - XmlAdaptedAppointment appointment = new XmlAdaptedAppointment(ALLY); - assertEquals(ALLY, appointment.toModelType()); + XmlAdaptedAppointment appointment = new XmlAdaptedAppointment(ALICE_APP); + assertEquals(ALICE_APP, appointment.toModelType()); } @Test diff --git a/src/test/java/seedu/address/testutil/TypicalAppointments.java b/src/test/java/seedu/address/testutil/TypicalAppointments.java index 36f1121e8d39..e5bf5fc4e5e2 100644 --- a/src/test/java/seedu/address/testutil/TypicalAppointments.java +++ b/src/test/java/seedu/address/testutil/TypicalAppointments.java @@ -11,22 +11,22 @@ */ public class TypicalAppointments { - public static final Appointment ALLY = new AppointmentBuilder() - .withOwnerNric("S9012345A") - .withPetPatientName("Hammy") + public static final Appointment ALICE_APP = new AppointmentBuilder() + .withOwnerNric(TypicalPersons.ALICE.getNric().toString()) + .withPetPatientName(TypicalPetPatients.JEWEL.getName().toString()) .withRemark("Requires Home Visit") .withDateTime("2018-12-31 12:30") .withAppointmentTags("checkup").build(); - public static final Appointment BENNY = new AppointmentBuilder() - .withOwnerNric("S1239049B") - .withPetPatientName("Lissy") + public static final Appointment BOB_APP = new AppointmentBuilder() + .withOwnerNric(TypicalPersons.BOB.getNric().toString()) + .withPetPatientName(TypicalPetPatients.JOKER.getName().toString()) .withRemark("May require isolation") .withDateTime("2018-12-31 14:30") - .withAppointmentTags("surgery").build(); + .withAppointmentTags("vaccination").build(); private TypicalAppointments() {} // prevents instantiation public static List getTypicalAppointments() { - return new ArrayList<>(Arrays.asList(ALLY, BENNY)); + return new ArrayList<>(Arrays.asList(ALICE_APP, BOB_APP)); } } diff --git a/src/test/java/seedu/address/testutil/TypicalPersons.java b/src/test/java/seedu/address/testutil/TypicalPersons.java index d1dbfa4b4e43..f90a0aa77334 100644 --- a/src/test/java/seedu/address/testutil/TypicalPersons.java +++ b/src/test/java/seedu/address/testutil/TypicalPersons.java @@ -82,6 +82,10 @@ public static AddressBook getTypicalAddressBook() { return ab; } + public static List getTypicalPersonsForDelete() { + return new ArrayList<>(Arrays.asList(ALICE, BOB)); + } + public static List getTypicalPersons() { return new ArrayList<>(Arrays.asList(ALICE, BENSON, CARL, DANIEL, ELLE, FIONA, GEORGE)); } diff --git a/src/test/java/seedu/address/testutil/TypicalPetPatients.java b/src/test/java/seedu/address/testutil/TypicalPetPatients.java index fe912e4f37ad..011bec7169c0 100644 --- a/src/test/java/seedu/address/testutil/TypicalPetPatients.java +++ b/src/test/java/seedu/address/testutil/TypicalPetPatients.java @@ -1,5 +1,9 @@ package seedu.address.testutil; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import seedu.address.model.petpatient.PetPatient; //@@author chialejing @@ -29,4 +33,8 @@ public class TypicalPetPatients { .withTags("Depression", "Test").build(); private TypicalPetPatients() {} + + public static List getTypicalPetPatients() { + return new ArrayList<>(Arrays.asList(JOKER, JEWEL)); + } } diff --git a/src/test/java/systemtests/DeleteCommandSystemTest.java b/src/test/java/systemtests/DeleteCommandSystemTest.java index c0de78e4aba6..d3836959e997 100644 --- a/src/test/java/systemtests/DeleteCommandSystemTest.java +++ b/src/test/java/systemtests/DeleteCommandSystemTest.java @@ -1,7 +1,7 @@ package systemtests; import static org.junit.Assert.assertTrue; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX; +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_DISPLAYED_INDEX; import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND; import static seedu.address.logic.commands.DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS; import static seedu.address.testutil.TestUtil.getLastIndex; @@ -20,11 +20,22 @@ import seedu.address.model.Model; import seedu.address.model.person.Person; import seedu.address.model.person.exceptions.PersonNotFoundException; +import seedu.address.model.petpatient.exceptions.PetDependencyNotEmptyException; public class DeleteCommandSystemTest extends AddressBookSystemTest { private static final String MESSAGE_INVALID_DELETE_COMMAND_FORMAT = String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE); + private static final String MESSAGE_INVALID_DELETE_COMMAND_FORMAT_OWNER = + String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE_OWNER); + private static final String MESSAGE_INVALID_DELETE_COMMAND_FORMAT_PET_PATIENT = + String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE_PET_PATIENT); + private static final String MESSAGE_INVALID_DELETE_COMMAND_FORMAT_FORCE_OWNER = + String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE_FORCE_OWNER); + private static final String MESSAGE_INVALID_DELETE_COMMAND_FORMAT_FORCE_PET_PATIENT = + String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE_FORCE_PET_PATIENT); + private static final String MESSAGE_INVALID_DELETE_COMMAND_FORMAT_APPOINTMENT = + String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE_APPOINTMENT); @Test public void delete() { @@ -32,7 +43,8 @@ public void delete() { /* Case: delete the first person in the list, command with leading spaces and trailing spaces -> deleted */ Model expectedModel = getModel(); - String command = " " + DeleteCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased() + " "; + String command = " " + DeleteCommand.COMMAND_WORD + " -o " + + INDEX_FIRST_PERSON.getOneBased() + " "; Person deletedPerson = removePerson(expectedModel, INDEX_FIRST_PERSON); String expectedResultMessage = String.format(MESSAGE_DELETE_PERSON_SUCCESS, deletedPerson); assertCommandSuccess(command, expectedModel, expectedResultMessage); @@ -70,8 +82,8 @@ public void delete() { */ showPersonsWithName(KEYWORD_MATCHING_MEIER); int invalidIndex = getModel().getAddressBook().getPersonList().size(); - command = DeleteCommand.COMMAND_WORD + " " + invalidIndex; - assertCommandFailure(command, MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + command = DeleteCommand.COMMAND_WORD + " -o " + invalidIndex; + assertCommandFailure(command, MESSAGE_INVALID_DISPLAYED_INDEX); /* --------------------- Performing delete operation while a person card is selected ------------------------ */ @@ -81,35 +93,169 @@ public void delete() { Index selectedIndex = getLastIndex(expectedModel); Index expectedIndex = Index.fromZeroBased(selectedIndex.getZeroBased() - 1); selectPerson(selectedIndex); - command = DeleteCommand.COMMAND_WORD + " " + selectedIndex.getOneBased(); + command = DeleteCommand.COMMAND_WORD + " -o " + selectedIndex.getOneBased(); deletedPerson = removePerson(expectedModel, selectedIndex); expectedResultMessage = String.format(MESSAGE_DELETE_PERSON_SUCCESS, deletedPerson); assertCommandSuccess(command, expectedModel, expectedResultMessage, expectedIndex); - /* --------------------------------- Performing invalid delete operation ------------------------------------ */ + /* ----------------------- Performing invalid delete operation for owner ------------------------------------ */ /* Case: invalid index (0) -> rejected */ - command = DeleteCommand.COMMAND_WORD + " 0"; - assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT); + command = DeleteCommand.COMMAND_WORD + " -o 0"; + assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT_OWNER); /* Case: invalid index (-1) -> rejected */ - command = DeleteCommand.COMMAND_WORD + " -1"; - assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT); + command = DeleteCommand.COMMAND_WORD + " -o -1"; + assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT_OWNER); /* Case: invalid index (size + 1) -> rejected */ Index outOfBoundsIndex = Index.fromOneBased( getModel().getAddressBook().getPersonList().size() + 1); - command = DeleteCommand.COMMAND_WORD + " " + outOfBoundsIndex.getOneBased(); - assertCommandFailure(command, MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + command = DeleteCommand.COMMAND_WORD + " -o " + outOfBoundsIndex.getOneBased(); + assertCommandFailure(command, MESSAGE_INVALID_DISPLAYED_INDEX); + + /* Case: invalid arguments (alphabets) -> rejected */ + assertCommandFailure(DeleteCommand.COMMAND_WORD + " -o abc", + MESSAGE_INVALID_DELETE_COMMAND_FORMAT_OWNER); + + /* Case: invalid arguments (extra argument) -> rejected */ + assertCommandFailure(DeleteCommand.COMMAND_WORD + " -o 1 abc", + MESSAGE_INVALID_DELETE_COMMAND_FORMAT_OWNER); + + /* Case: mixed case command word -> rejected */ + assertCommandFailure("DelETE -o 1", MESSAGE_UNKNOWN_COMMAND); + + /* ------------------ Performing invalid delete operation for appointment ----------------------------------- */ + + /* Case: invalid index (0) -> rejected */ + command = DeleteCommand.COMMAND_WORD + " -a 0"; + assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT_APPOINTMENT); + + /* Case: invalid index (-1) -> rejected */ + command = DeleteCommand.COMMAND_WORD + " -a -1"; + assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT_APPOINTMENT); + + /* Case: invalid index (size + 1) -> rejected */ + outOfBoundsIndex = Index.fromOneBased( + getModel().getAddressBook().getAppointmentList().size() + 1); + command = DeleteCommand.COMMAND_WORD + " -a " + outOfBoundsIndex.getOneBased(); + assertCommandFailure(command, MESSAGE_INVALID_DISPLAYED_INDEX); + + /* Case: invalid arguments (alphabets) -> rejected */ + assertCommandFailure(DeleteCommand.COMMAND_WORD + " -a abc", + MESSAGE_INVALID_DELETE_COMMAND_FORMAT_APPOINTMENT); + + /* Case: invalid arguments (extra argument) -> rejected */ + assertCommandFailure(DeleteCommand.COMMAND_WORD + " -a 1 abc", + MESSAGE_INVALID_DELETE_COMMAND_FORMAT_APPOINTMENT); + + /* Case: mixed case command word -> rejected */ + assertCommandFailure("DelETE -a 1", MESSAGE_UNKNOWN_COMMAND); + + /* ------------------ Performing invalid delete operation for pet patient ----------------------------------- */ + + /* Case: invalid index (0) -> rejected */ + command = DeleteCommand.COMMAND_WORD + " -p 0"; + assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT_PET_PATIENT); + + /* Case: invalid index (-1) -> rejected */ + command = DeleteCommand.COMMAND_WORD + " -p -1"; + assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT_PET_PATIENT); + + /* Case: invalid index (size + 1) -> rejected */ + outOfBoundsIndex = Index.fromOneBased( + getModel().getAddressBook().getPetPatientList().size() + 1); + command = DeleteCommand.COMMAND_WORD + " -p " + outOfBoundsIndex.getOneBased(); + assertCommandFailure(command, MESSAGE_INVALID_DISPLAYED_INDEX); + + /* Case: invalid arguments (alphabets) -> rejected */ + assertCommandFailure(DeleteCommand.COMMAND_WORD + " -p abc", + MESSAGE_INVALID_DELETE_COMMAND_FORMAT_PET_PATIENT); + + /* Case: invalid arguments (extra argument) -> rejected */ + assertCommandFailure(DeleteCommand.COMMAND_WORD + " -p 1 abc", + MESSAGE_INVALID_DELETE_COMMAND_FORMAT_PET_PATIENT); + + /* Case: mixed case command word -> rejected */ + assertCommandFailure("DelETE -p 1", MESSAGE_UNKNOWN_COMMAND); + + /* ----------------------- Performing invalid delete operation for force owner ------------------------------ */ + + /* Case: invalid index (0) -> rejected */ + command = DeleteCommand.COMMAND_WORD + " -fo 0"; + assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT_FORCE_OWNER); + + /* Case: invalid index (-1) -> rejected */ + command = DeleteCommand.COMMAND_WORD + " -fo -1"; + assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT_FORCE_OWNER); + + /* Case: invalid index (size + 1) -> rejected */ + outOfBoundsIndex = Index.fromOneBased( + getModel().getAddressBook().getPersonList().size() + 1); + command = DeleteCommand.COMMAND_WORD + " -fo " + outOfBoundsIndex.getOneBased(); + assertCommandFailure(command, MESSAGE_INVALID_DISPLAYED_INDEX); + + /* Case: invalid arguments (alphabets) -> rejected */ + assertCommandFailure(DeleteCommand.COMMAND_WORD + " -fo abc", + MESSAGE_INVALID_DELETE_COMMAND_FORMAT_FORCE_OWNER); + + /* Case: invalid arguments (extra argument) -> rejected */ + assertCommandFailure(DeleteCommand.COMMAND_WORD + " -fo 1 abc", + MESSAGE_INVALID_DELETE_COMMAND_FORMAT_FORCE_OWNER); + + /* Case: mixed case command word -> rejected */ + assertCommandFailure("DelETE -fo 1", MESSAGE_UNKNOWN_COMMAND); + + /* ----------------------- Performing invalid delete operation for force pet patient ------------------------ */ + + /* Case: invalid index (0) -> rejected */ + command = DeleteCommand.COMMAND_WORD + " -fp 0"; + assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT_FORCE_PET_PATIENT); + + /* Case: invalid index (-1) -> rejected */ + command = DeleteCommand.COMMAND_WORD + " -fp -1"; + assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT_FORCE_PET_PATIENT); + + /* Case: invalid index (size + 1) -> rejected */ + outOfBoundsIndex = Index.fromOneBased( + getModel().getAddressBook().getPersonList().size() + 1); + command = DeleteCommand.COMMAND_WORD + " -fp " + outOfBoundsIndex.getOneBased(); + assertCommandFailure(command, MESSAGE_INVALID_DISPLAYED_INDEX); /* Case: invalid arguments (alphabets) -> rejected */ - assertCommandFailure(DeleteCommand.COMMAND_WORD + " abc", MESSAGE_INVALID_DELETE_COMMAND_FORMAT); + assertCommandFailure(DeleteCommand.COMMAND_WORD + " -fp abc", + MESSAGE_INVALID_DELETE_COMMAND_FORMAT_FORCE_PET_PATIENT); /* Case: invalid arguments (extra argument) -> rejected */ - assertCommandFailure(DeleteCommand.COMMAND_WORD + " 1 abc", MESSAGE_INVALID_DELETE_COMMAND_FORMAT); + assertCommandFailure(DeleteCommand.COMMAND_WORD + " -fp 1 abc", + MESSAGE_INVALID_DELETE_COMMAND_FORMAT_FORCE_PET_PATIENT); /* Case: mixed case command word -> rejected */ - assertCommandFailure("DelETE 1", MESSAGE_UNKNOWN_COMMAND); + assertCommandFailure("DelETE -fp 1", MESSAGE_UNKNOWN_COMMAND); + + /* ------------------------- Performing invalid delete operation with wrong type ---------------------------- */ + + /* Case: invalid index (0) -> rejected */ + command = DeleteCommand.COMMAND_WORD + " -sha 0"; + assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT); + + /* Case: invalid index (-1) -> rejected */ + command = DeleteCommand.COMMAND_WORD + " -fza -1"; + assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT); + + /* Case: invalid index (size + 1) -> rejected */ + outOfBoundsIndex = Index.fromOneBased( + getModel().getAddressBook().getPersonList().size() + 1); + command = DeleteCommand.COMMAND_WORD + " -fup " + outOfBoundsIndex.getOneBased(); + assertCommandFailure(command, MESSAGE_INVALID_DELETE_COMMAND_FORMAT); + + /* Case: invalid arguments (alphabets) -> rejected */ + assertCommandFailure(DeleteCommand.COMMAND_WORD + " -fsp abc", + MESSAGE_INVALID_DELETE_COMMAND_FORMAT); + + /* Case: invalid arguments (extra argument) -> rejected */ + assertCommandFailure(DeleteCommand.COMMAND_WORD + " -nafp 1 abc", + MESSAGE_INVALID_DELETE_COMMAND_FORMAT); } /** @@ -122,6 +268,8 @@ private Person removePerson(Model model, Index index) { model.deletePerson(targetPerson); } catch (PersonNotFoundException pnfe) { throw new AssertionError("targetPerson is retrieved from model."); + } catch (PetDependencyNotEmptyException e) { + throw new AssertionError("targetPerson is retrieved from model."); } return targetPerson; } @@ -137,7 +285,8 @@ private void assertCommandSuccess(Index toDelete) { String expectedResultMessage = String.format(MESSAGE_DELETE_PERSON_SUCCESS, deletedPerson); assertCommandSuccess( - DeleteCommand.COMMAND_WORD + " " + toDelete.getOneBased(), expectedModel, expectedResultMessage); + DeleteCommand.COMMAND_WORD + " -o " + toDelete.getOneBased(), + expectedModel, expectedResultMessage); } /** diff --git a/src/test/java/systemtests/EditCommandSystemTest.java b/src/test/java/systemtests/EditCommandSystemTest.java index 8c3973c6a7f4..e8c7d5c44aa2 100644 --- a/src/test/java/systemtests/EditCommandSystemTest.java +++ b/src/test/java/systemtests/EditCommandSystemTest.java @@ -125,9 +125,11 @@ public void edit() throws Exception { */ showPersonsWithName(KEYWORD_MATCHING_MEIER); int invalidIndex = getModel().getAddressBook().getPersonList().size(); + assertCommandFailure(EditCommand.COMMAND_WORD + OPTION_OWNER + " " + invalidIndex + NAME_DESC_BOB, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + /* --------------------- Performing edit operation while a person card is selected -------------------------- */ /* Case: selects first card in the person list, edit a person -> edited, card selection remains unchanged but @@ -155,9 +157,11 @@ public void edit() throws Exception { /* Case: invalid index (size + 1) -> rejected */ invalidIndex = getModel().getFilteredPersonList().size() + 1; + assertCommandFailure(EditCommand.COMMAND_WORD + OPTION_OWNER + " " + invalidIndex + NAME_DESC_BOB, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + /* Case: missing index -> rejected */ assertCommandFailure(EditCommand.COMMAND_WORD + OPTION_OWNER + NAME_DESC_BOB, String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE)); diff --git a/src/test/java/systemtests/FindCommandSystemTest.java b/src/test/java/systemtests/FindCommandSystemTest.java index 0bde83c0444b..f81e20149bec 100644 --- a/src/test/java/systemtests/FindCommandSystemTest.java +++ b/src/test/java/systemtests/FindCommandSystemTest.java @@ -81,7 +81,7 @@ public void find() { assertCommandFailure(command, expectedResultMessage); /* Case: find same persons in address book after deleting 1 of them -> 1 person found */ - executeCommand(DeleteCommand.COMMAND_WORD + " 1"); + executeCommand(DeleteCommand.COMMAND_WORD + " -fo 1"); assertFalse(getModel().getAddressBook().getPersonList().contains(BENSON)); command = FindCommand.COMMAND_WORD + " " + KEYWORD_MATCHING_MEIER; expectedModel = getModel(); diff --git a/src/test/java/systemtests/HelpCommandSystemTest.java b/src/test/java/systemtests/HelpCommandSystemTest.java index 0ab0f154bb85..117c9a5eed0f 100644 --- a/src/test/java/systemtests/HelpCommandSystemTest.java +++ b/src/test/java/systemtests/HelpCommandSystemTest.java @@ -73,7 +73,7 @@ public void openHelpWindow() { // assert that the status bar too is updated correctly while the help window is open // note: the select command tested above does not update the status bar - executeCommand(DeleteCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased()); + executeCommand(DeleteCommand.COMMAND_WORD + " -o " + INDEX_FIRST_PERSON.getOneBased()); assertNotEquals(StatusBarFooter.SYNC_STATUS_INITIAL, getStatusBarFooter().getSyncStatus()); } diff --git a/src/test/java/systemtests/SelectCommandSystemTest.java b/src/test/java/systemtests/SelectCommandSystemTest.java index c7deb73454b1..f94c9684bd1d 100644 --- a/src/test/java/systemtests/SelectCommandSystemTest.java +++ b/src/test/java/systemtests/SelectCommandSystemTest.java @@ -2,7 +2,7 @@ import static org.junit.Assert.assertTrue; import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX; +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_DISPLAYED_INDEX; import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND; import static seedu.address.logic.commands.SelectCommand.MESSAGE_SELECT_PERSON_SUCCESS; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; @@ -58,7 +58,7 @@ public void select() { */ showPersonsWithName(KEYWORD_MATCHING_MEIER); int invalidIndex = getModel().getAddressBook().getPersonList().size(); - assertCommandFailure(SelectCommand.COMMAND_WORD + " " + invalidIndex, MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandFailure(SelectCommand.COMMAND_WORD + " " + invalidIndex, MESSAGE_INVALID_DISPLAYED_INDEX); /* Case: filtered person list, select index within bounds of address book and person list -> selected */ Index validIndex = Index.fromOneBased(1); @@ -78,7 +78,7 @@ public void select() { /* Case: invalid index (size + 1) -> rejected */ invalidIndex = getModel().getFilteredPersonList().size() + 1; - assertCommandFailure(SelectCommand.COMMAND_WORD + " " + invalidIndex, MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandFailure(SelectCommand.COMMAND_WORD + " " + invalidIndex, MESSAGE_INVALID_DISPLAYED_INDEX); /* Case: invalid arguments (alphabets) -> rejected */ assertCommandFailure(SelectCommand.COMMAND_WORD + " abc", @@ -94,7 +94,7 @@ public void select() { /* Case: select from empty address book -> rejected */ deleteAllPersons(); assertCommandFailure(SelectCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased(), - MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + MESSAGE_INVALID_DISPLAYED_INDEX); } /**