From 786b65aea25a5a2d8fc4f86ea83b6595fe124c78 Mon Sep 17 00:00:00 2001 From: saraozn Date: Wed, 25 Oct 2023 18:45:40 +0800 Subject: [PATCH] add editprop command --- .../logic/commands/EditPropertyCommand.java | 243 ++++++++++++++++++ .../logic/parser/AddressBookParser.java | 4 + .../parser/EditPropertyCommandParser.java | 86 +++++++ .../address/model/ReadOnlyAddressBook.java | 1 - .../AddCustomerCommandIntegrationTest.java | 3 +- .../AddPropertyCommandIntegrationTest.java | 3 +- .../logic/commands/ClearCommandTest.java | 6 +- .../commands/CommandPropertyTestUtil.java | 26 +- .../commands/DeleteCustomerCommandTest.java | 3 +- .../commands/DeletePropertyCommandTest.java | 3 +- .../logic/commands/EditCommandTest.java | 3 +- .../commands/EditPropertyCommandTest.java | 195 ++++++++++++++ .../logic/commands/FindCommandTest.java | 6 +- .../logic/commands/ListCommandTest.java | 3 +- .../logic/parser/AddressBookParserTest.java | 24 +- .../parser/EditPropertyCommandParserTest.java | 208 +++++++++++++++ .../seedu/address/model/AddressBookTest.java | 1 - .../EditPropertyDescriptorBuilder.java | 87 +++++++ .../seedu/address/testutil/PropertyUtil.java | 33 ++- 19 files changed, 904 insertions(+), 34 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/EditPropertyCommand.java create mode 100644 src/main/java/seedu/address/logic/parser/EditPropertyCommandParser.java create mode 100644 src/test/java/seedu/address/logic/commands/EditPropertyCommandTest.java create mode 100644 src/test/java/seedu/address/logic/parser/EditPropertyCommandParserTest.java create mode 100644 src/test/java/seedu/address/testutil/EditPropertyDescriptorBuilder.java diff --git a/src/main/java/seedu/address/logic/commands/EditPropertyCommand.java b/src/main/java/seedu/address/logic/commands/EditPropertyCommand.java new file mode 100644 index 00000000000..41ea573c8e0 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/EditPropertyCommand.java @@ -0,0 +1,243 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PRICE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PROPERTIES; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; + +import seedu.address.commons.core.index.Index; +import seedu.address.commons.util.CollectionUtil; +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.property.Price; +import seedu.address.model.property.PropAddress; +import seedu.address.model.property.PropName; +import seedu.address.model.property.PropPhone; +import seedu.address.model.property.Property; +import seedu.address.model.tag.Tag; + +/** + * Edits the details of an existing property in the Price book. + */ +public class EditPropertyCommand extends Command { + + public static final String COMMAND_WORD = "editprop"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the details of the property identified " + + "by the index number used in the displayed property list. " + + "Existing values will be overwritten by the input values.\n" + + "Parameters: INDEX (must be a positive integer) " + + "[" + PREFIX_NAME + "NAME] " + + "[" + PREFIX_PHONE + "PHONE] " + + "[" + PREFIX_ADDRESS + "ADDRESS] " + + "[" + PREFIX_PRICE + "PRICE] " + + "[" + PREFIX_TAG + "TAG]...\n" + + "Example: " + COMMAND_WORD + " 1 " + + PREFIX_PHONE + "91234567 " + + PREFIX_ADDRESS + "311, Clementi Ave 2, #02-25"; + + public static final String MESSAGE_EDIT_PROPERTY_SUCCESS = "Edited property: %1$s"; + public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided."; + public static final String MESSAGE_DUPLICATE_PROPERTY = "This property already exists in PropertyMatch."; + + private final Index index; + private final EditPropertyDescriptor editPropertyDescriptor; + + /** + * @param index of the property in the filtered property list to edit + * @param editPropertyDescriptor details to edit the property with + */ + public EditPropertyCommand(Index index, EditPropertyDescriptor editPropertyDescriptor) { + requireNonNull(index); + requireNonNull(editPropertyDescriptor); + + this.index = index; + this.editPropertyDescriptor = new EditPropertyDescriptor(editPropertyDescriptor); + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + List lastShownList = model.getFilteredPropertyList(); + + if (index.getZeroBased() >= lastShownList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_PROPERTY_DISPLAYED_INDEX); + } + + Property propertyToEdit = lastShownList.get(index.getZeroBased()); + Property editedproperty = createEditedproperty(propertyToEdit, editPropertyDescriptor); + + if (!propertyToEdit.isSameProperty(editedproperty) && model.hasProperty(editedproperty)) { + throw new CommandException(MESSAGE_DUPLICATE_PROPERTY); + } + + model.setProperty(propertyToEdit, editedproperty); + model.updateFilteredPropertyList(PREDICATE_SHOW_ALL_PROPERTIES); + return new CommandResult(String.format(MESSAGE_EDIT_PROPERTY_SUCCESS, Messages.format(editedproperty))); + } + + /** + * Creates and returns a {@code property} with the details of {@code propertyToEdit} + * edited with {@code editpropertyDescriptor}. + */ + private static Property createEditedproperty(Property propertyToEdit, + EditPropertyDescriptor editpropertyDescriptor) { + assert propertyToEdit != null; + + PropName updatedName = editpropertyDescriptor.getName().orElse(propertyToEdit.getName()); + PropPhone updatedPhone = editpropertyDescriptor.getPhone().orElse(propertyToEdit.getPhone()); + PropAddress updatedAddress = editpropertyDescriptor.getAddress().orElse(propertyToEdit.getAddress()); + Price updatedPrice = editpropertyDescriptor.getPrice().orElse(propertyToEdit.getPrice()); + Set updatedTags = editpropertyDescriptor.getTags().orElse(propertyToEdit.getTags()); + + return new Property(updatedName, updatedAddress, updatedPhone, updatedPrice, updatedTags); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof EditPropertyCommand)) { + return false; + } + + EditPropertyCommand otherEditCommand = (EditPropertyCommand) other; + return index.equals(otherEditCommand.index) + && editPropertyDescriptor.equals(otherEditCommand.editPropertyDescriptor); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("index", index) + .add("editPropertyDescriptor", editPropertyDescriptor) + .toString(); + } + + /** + * Stores the details to edit the property with. Each non-empty field value will replace the + * corresponding field value of the property. + */ + public static class EditPropertyDescriptor { + private PropName name; + private PropPhone phone; + private PropAddress address; + private Price price; + private Set tags; + + public EditPropertyDescriptor() {} + + /** + * Copy constructor. + * A defensive copy of {@code tags} is used internally. + */ + public EditPropertyDescriptor(EditPropertyDescriptor toCopy) { + setName(toCopy.name); + setPhone(toCopy.phone); + setAddress(toCopy.address); + setPrice(toCopy.price); + setTags(toCopy.tags); + } + + /** + * Returns true if at least one field is edited. + */ + public boolean isAnyFieldEdited() { + return CollectionUtil.isAnyNonNull(name, phone, address, price, tags); + } + + public void setName(PropName name) { + this.name = name; + } + + public Optional getName() { + return Optional.ofNullable(name); + } + + public void setPhone(PropPhone phone) { + this.phone = phone; + } + + public Optional getPhone() { + return Optional.ofNullable(phone); + } + + public void setAddress(PropAddress address) { + this.address = address; + } + + public Optional getAddress() { + return Optional.ofNullable(address); + } + + public void setPrice(Price price) { + this.price = price; + } + + public Optional getPrice() { + return Optional.ofNullable(price); + } + + /** + * Sets {@code tags} to this object's {@code tags}. + * A defensive copy of {@code tags} is used internally. + */ + public void setTags(Set tags) { + this.tags = (tags != null) ? new HashSet<>(tags) : null; + } + + /** + * Returns an unmodifiable tag set, which throws {@code UnsupportedOperationException} + * if modification is attempted. + * Returns {@code Optional#empty()} if {@code tags} is null. + */ + public Optional> getTags() { + return (tags != null) ? Optional.of(Collections.unmodifiableSet(tags)) : Optional.empty(); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof EditPropertyDescriptor)) { + return false; + } + + EditPropertyDescriptor otherEditpropertyDescriptor = (EditPropertyDescriptor) other; + return Objects.equals(name, otherEditpropertyDescriptor.name) + && Objects.equals(phone, otherEditpropertyDescriptor.phone) + && Objects.equals(address, otherEditpropertyDescriptor.address) + && Objects.equals(price, otherEditpropertyDescriptor.price) + && Objects.equals(tags, otherEditpropertyDescriptor.tags); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("name", name) + .add("phone", phone) + .add("address", address) + .add("price", price) + .add("tags", tags) + .toString(); + } + } +} diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 768306ab7fd..507ecaf16f1 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -15,6 +15,7 @@ import seedu.address.logic.commands.DeleteCustomerCommand; import seedu.address.logic.commands.DeletePropertyCommand; import seedu.address.logic.commands.EditCommand; +import seedu.address.logic.commands.EditPropertyCommand; import seedu.address.logic.commands.ExitCommand; import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.HelpCommand; @@ -65,6 +66,9 @@ public Command parseCommand(String userInput) throws ParseException { case EditCommand.COMMAND_WORD: return new EditCommandParser().parse(arguments); + case EditPropertyCommand.COMMAND_WORD: + return new EditPropertyCommandParser().parse(arguments); + case DeletePropertyCommand.COMMAND_WORD: return new DeletePropertyCommandParser().parse(arguments); diff --git a/src/main/java/seedu/address/logic/parser/EditPropertyCommandParser.java b/src/main/java/seedu/address/logic/parser/EditPropertyCommandParser.java new file mode 100644 index 00000000000..f43bf1a6e4a --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/EditPropertyCommandParser.java @@ -0,0 +1,86 @@ +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_ADDRESS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PRICE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; + +import java.util.Collection; +import java.util.Collections; +import java.util.Optional; +import java.util.Set; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.EditPropertyCommand; +import seedu.address.logic.commands.EditPropertyCommand.EditPropertyDescriptor; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.tag.Tag; + +/** + * Parses input arguments and creates a new EditCommand object + */ +public class EditPropertyCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the EditCommand + * and returns an EditCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public EditPropertyCommand parse(String args) throws ParseException { + requireNonNull(args); + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_ADDRESS, PREFIX_PRICE, PREFIX_TAG); + + Index index; + + try { + index = ParserUtil.parseIndex(argMultimap.getPreamble()); + } catch (ParseException pe) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + EditPropertyCommand.MESSAGE_USAGE), pe); + } + + argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_ADDRESS, PREFIX_PRICE); + + EditPropertyDescriptor editPropertyDescriptor = new EditPropertyDescriptor(); + + if (argMultimap.getValue(PREFIX_NAME).isPresent()) { + editPropertyDescriptor.setName(ParserUtil.parsePropName(argMultimap.getValue(PREFIX_NAME).get())); + } + if (argMultimap.getValue(PREFIX_PHONE).isPresent()) { + editPropertyDescriptor.setPhone(ParserUtil.parsePropPhone(argMultimap.getValue(PREFIX_PHONE).get())); + } + if (argMultimap.getValue(PREFIX_ADDRESS).isPresent()) { + editPropertyDescriptor.setAddress(ParserUtil.parsePropAddress(argMultimap.getValue(PREFIX_ADDRESS).get())); + } + if (argMultimap.getValue(PREFIX_PRICE).isPresent()) { + editPropertyDescriptor.setPrice(ParserUtil.parsePrice(argMultimap.getValue(PREFIX_PRICE).get())); + } + parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editPropertyDescriptor::setTags); + + if (!editPropertyDescriptor.isAnyFieldEdited()) { + throw new ParseException(EditPropertyCommand.MESSAGE_NOT_EDITED); + } + + return new EditPropertyCommand(index, editPropertyDescriptor); + } + + /** + * Parses {@code Collection tags} into a {@code Set} if {@code tags} is non-empty. + * If {@code tags} contain only one element which is an empty string, it will be parsed into a + * {@code Set} containing zero tags. + */ + private Optional> parseTagsForEdit(Collection tags) throws ParseException { + assert tags != null; + + if (tags.isEmpty()) { + return Optional.empty(); + } + Collection tagSet = tags.size() == 1 && tags.contains("") ? Collections.emptySet() : tags; + return Optional.of(ParserUtil.parseTags(tagSet)); + } + +} diff --git a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java index 7f0b9992b80..bc627f9e86e 100644 --- a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java +++ b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java @@ -13,5 +13,4 @@ public interface ReadOnlyAddressBook { * This list will not contain any duplicate customers. */ ObservableList getCustomerList(); - } diff --git a/src/test/java/seedu/address/logic/commands/AddCustomerCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/AddCustomerCommandIntegrationTest.java index 59d4b139622..447b4532eb1 100644 --- a/src/test/java/seedu/address/logic/commands/AddCustomerCommandIntegrationTest.java +++ b/src/test/java/seedu/address/logic/commands/AddCustomerCommandIntegrationTest.java @@ -3,6 +3,7 @@ import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.testutil.TypicalCustomers.getTypicalAddressBook; +import static seedu.address.testutil.TypicalProperties.getTypicalPropertyBook; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -24,7 +25,7 @@ public class AddCustomerCommandIntegrationTest { @BeforeEach public void setUp() { - model = new ModelManager(getTypicalAddressBook(), new PropertyBook(), new UserPrefs()); + model = new ModelManager(getTypicalAddressBook(), getTypicalPropertyBook(), new UserPrefs()); } @Test diff --git a/src/test/java/seedu/address/logic/commands/AddPropertyCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/AddPropertyCommandIntegrationTest.java index aeca9057e8d..6f6e58ed3de 100644 --- a/src/test/java/seedu/address/logic/commands/AddPropertyCommandIntegrationTest.java +++ b/src/test/java/seedu/address/logic/commands/AddPropertyCommandIntegrationTest.java @@ -3,6 +3,7 @@ import static seedu.address.logic.commands.CommandPropertyTestUtil.assertCommandFailure; import static seedu.address.logic.commands.CommandPropertyTestUtil.assertCommandSuccess; import static seedu.address.testutil.TypicalCustomers.getTypicalAddressBook; +import static seedu.address.testutil.TypicalProperties.getTypicalPropertyBook; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -24,7 +25,7 @@ public class AddPropertyCommandIntegrationTest { @BeforeEach public void setUp() { - model = new ModelManager(getTypicalAddressBook(), new PropertyBook(), new UserPrefs()); + model = new ModelManager(getTypicalAddressBook(), getTypicalPropertyBook(), new UserPrefs()); } @Test diff --git a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java index 036a49fccea..8f184a95b2e 100644 --- a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java @@ -2,13 +2,13 @@ import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.testutil.TypicalCustomers.getTypicalAddressBook; +import static seedu.address.testutil.TypicalProperties.getTypicalPropertyBook; import org.junit.jupiter.api.Test; import seedu.address.model.AddressBook; import seedu.address.model.Model; import seedu.address.model.ModelManager; -import seedu.address.model.PropertyBook; import seedu.address.model.UserPrefs; public class ClearCommandTest { @@ -23,8 +23,8 @@ public void execute_emptyAddressBook_success() { @Test public void execute_nonEmptyAddressBook_success() { - Model model = new ModelManager(getTypicalAddressBook(), new PropertyBook(), new UserPrefs()); - Model expectedModel = new ModelManager(getTypicalAddressBook(), new PropertyBook(), new UserPrefs()); + Model model = new ModelManager(getTypicalAddressBook(), getTypicalPropertyBook(), new UserPrefs()); + Model expectedModel = new ModelManager(getTypicalAddressBook(), getTypicalPropertyBook(), new UserPrefs()); expectedModel.setAddressBook(new AddressBook()); assertCommandSuccess(new ClearCommand(), model, ClearCommand.MESSAGE_SUCCESS, expectedModel); diff --git a/src/test/java/seedu/address/logic/commands/CommandPropertyTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandPropertyTestUtil.java index 5ac2ea7ebb0..c877a970dbf 100644 --- a/src/test/java/seedu/address/logic/commands/CommandPropertyTestUtil.java +++ b/src/test/java/seedu/address/logic/commands/CommandPropertyTestUtil.java @@ -19,6 +19,7 @@ import seedu.address.model.PropertyBook; import seedu.address.model.property.PropNameContainsKeywordsPredicate; import seedu.address.model.property.Property; +import seedu.address.testutil.EditPropertyDescriptorBuilder; /** * Contains helper methods for testing commands. @@ -56,19 +57,18 @@ public class CommandPropertyTestUtil { public static final String PREAMBLE_WHITESPACE = "\t \r \n"; public static final String PREAMBLE_NON_EMPTY = "NonEmptyPreamble"; - //uncomment after editprop command is done - // public static final EditCommand.EditPropertyDescriptor DESC_AQUAVIEW; - // public static final EditCommand.EditPropertyDescriptor DESC_SKYVIEW; - // - // static { - // DESC_AQUAVIEW = new EditPropertyDescriptorBuilder().withName(VALID_NAME_AQUAVIEW) - // .withPhone(VALID_PHONE_AQUAVIEW).withAddress(VALID_ADDRESS_AQUAVIEW) - // .withPrice(VALID_PRICE_AQUAVIEW) - // .withTags(VALID_TAG_SQUARE).build(); - // DESC_SKYVIEW = new EditPropertyDescriptorBuilder().withName(VALID_NAME_SKYVIEW) - // .withPhone(VALID_PHONE_SKYVIEW).withAddress(VALID_ADDRESS_SKYVIEW).withPrice(VALID_PRICE_SKYVIEW) - // .withTags(VALID_TAG_BIG, VALID_TAG_SQUARE).build(); - // } + public static final EditPropertyCommand.EditPropertyDescriptor DESC_AQUAVIEW; + public static final EditPropertyCommand.EditPropertyDescriptor DESC_SKYVIEW; + + static { + DESC_AQUAVIEW = new EditPropertyDescriptorBuilder().withName(VALID_NAME_AQUAVIEW) + .withPhone(VALID_PHONE_AQUAVIEW).withAddress(VALID_ADDRESS_AQUAVIEW) + .withPrice(VALID_PRICE_AQUAVIEW) + .withTags(VALID_TAG_SQUARE).build(); + DESC_SKYVIEW = new EditPropertyDescriptorBuilder().withName(VALID_NAME_SKYVIEW) + .withPhone(VALID_PHONE_SKYVIEW).withAddress(VALID_ADDRESS_SKYVIEW).withPrice(VALID_PRICE_SKYVIEW) + .withTags(VALID_TAG_BIG, VALID_TAG_SQUARE).build(); + } /** * Executes the given {@code command}, confirms that
diff --git a/src/test/java/seedu/address/logic/commands/DeleteCustomerCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteCustomerCommandTest.java index 1229a867f51..10b1306b559 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteCustomerCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteCustomerCommandTest.java @@ -9,6 +9,7 @@ import static seedu.address.testutil.TypicalCustomers.getTypicalAddressBook; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_CUSTOMER; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_CUSTOMER; +import static seedu.address.testutil.TypicalProperties.getTypicalPropertyBook; import org.junit.jupiter.api.Test; @@ -25,7 +26,7 @@ */ public class DeleteCustomerCommandTest { - private Model model = new ModelManager(getTypicalAddressBook(), new PropertyBook(), new UserPrefs()); + private Model model = new ModelManager(getTypicalAddressBook(), getTypicalPropertyBook(), new UserPrefs()); @Test public void execute_validIndexUnfilteredList_success() { diff --git a/src/test/java/seedu/address/logic/commands/DeletePropertyCommandTest.java b/src/test/java/seedu/address/logic/commands/DeletePropertyCommandTest.java index 34390d0149e..9ce1d500494 100644 --- a/src/test/java/seedu/address/logic/commands/DeletePropertyCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeletePropertyCommandTest.java @@ -9,6 +9,7 @@ import static seedu.address.testutil.TypicalCustomers.getTypicalAddressBook; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PROPERTY; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PROPERTY; +import static seedu.address.testutil.TypicalProperties.getTypicalPropertyBook; import org.junit.jupiter.api.Test; @@ -26,7 +27,7 @@ */ public class DeletePropertyCommandTest { - private Model model = new ModelManager(getTypicalAddressBook(), new PropertyBook(), new UserPrefs()); + private Model model = new ModelManager(getTypicalAddressBook(), getTypicalPropertyBook(), new UserPrefs()); @Test public void execute_validIndexUnfilteredList_success() { diff --git a/src/test/java/seedu/address/logic/commands/EditCommandTest.java b/src/test/java/seedu/address/logic/commands/EditCommandTest.java index 27b42713546..339637ad2e8 100644 --- a/src/test/java/seedu/address/logic/commands/EditCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/EditCommandTest.java @@ -14,6 +14,7 @@ import static seedu.address.testutil.TypicalCustomers.getTypicalAddressBook; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_CUSTOMER; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_CUSTOMER; +import static seedu.address.testutil.TypicalProperties.getTypicalPropertyBook; import org.junit.jupiter.api.Test; @@ -34,7 +35,7 @@ */ public class EditCommandTest { - private Model model = new ModelManager(getTypicalAddressBook(), new PropertyBook(), new UserPrefs()); + private Model model = new ModelManager(getTypicalAddressBook(), getTypicalPropertyBook(), new UserPrefs()); @Test public void execute_allFieldsSpecifiedUnfilteredList_success() { diff --git a/src/test/java/seedu/address/logic/commands/EditPropertyCommandTest.java b/src/test/java/seedu/address/logic/commands/EditPropertyCommandTest.java new file mode 100644 index 00000000000..ddf5ac12628 --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/EditPropertyCommandTest.java @@ -0,0 +1,195 @@ +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.CommandPropertyTestUtil.DESC_AQUAVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.DESC_SKYVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.VALID_NAME_SKYVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.VALID_PHONE_SKYVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.VALID_TAG_BIG; +import static seedu.address.logic.commands.CommandPropertyTestUtil.assertCommandFailure; +import static seedu.address.logic.commands.CommandPropertyTestUtil.assertCommandSuccess; +import static seedu.address.logic.commands.CommandPropertyTestUtil.showPropertyAtIndex; +import static seedu.address.testutil.TypicalCustomers.getTypicalAddressBook; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PROPERTY; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PROPERTY; +import static seedu.address.testutil.TypicalProperties.getTypicalPropertyBook; + +import org.junit.jupiter.api.Test; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.Messages; +import seedu.address.logic.commands.EditPropertyCommand.EditPropertyDescriptor; +import seedu.address.model.AddressBook; +import seedu.address.model.Model; +import seedu.address.model.ModelManager; +import seedu.address.model.PropertyBook; +import seedu.address.model.UserPrefs; +import seedu.address.model.property.Property; +import seedu.address.testutil.EditPropertyDescriptorBuilder; +import seedu.address.testutil.PropertyBuilder; + + +/** + * Contains integration tests (interaction with the Model) and unit tests for EditCommand. + */ +public class EditPropertyCommandTest { + + private Model model = new ModelManager(getTypicalAddressBook(), getTypicalPropertyBook(), new UserPrefs()); + + @Test + public void execute_allFieldsSpecifiedUnfilteredList_success() { + Property editedProperty = new PropertyBuilder().build(); + EditPropertyDescriptor descriptor = new EditPropertyDescriptorBuilder(editedProperty).build(); + EditPropertyCommand editCommand = new EditPropertyCommand(INDEX_FIRST_PROPERTY, descriptor); + + String expectedMessage = String.format(EditPropertyCommand.MESSAGE_EDIT_PROPERTY_SUCCESS, + Messages.format(editedProperty)); + + Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), + new PropertyBook(), new UserPrefs()); + expectedModel.setProperty(model.getFilteredPropertyList().get(0), editedProperty); + + assertCommandSuccess(editCommand, model, expectedMessage, expectedModel); + } + + @Test + public void execute_someFieldsSpecifiedUnfilteredList_success() { + Index indexLastProperty = Index.fromOneBased(model.getFilteredPropertyList().size()); + Property lastProperty = model.getFilteredPropertyList().get(indexLastProperty.getZeroBased()); + + PropertyBuilder propertyInList = new PropertyBuilder(lastProperty); + Property editedProperty = propertyInList.withName(VALID_NAME_SKYVIEW).withPhone(VALID_PHONE_SKYVIEW) + .withTags(VALID_TAG_BIG).build(); + + EditPropertyDescriptor descriptor = new EditPropertyDescriptorBuilder().withName(VALID_NAME_SKYVIEW) + .withPhone(VALID_PHONE_SKYVIEW).withTags(VALID_TAG_BIG).build(); + EditPropertyCommand editCommand = new EditPropertyCommand(indexLastProperty, descriptor); + + String expectedMessage = String.format(EditPropertyCommand.MESSAGE_EDIT_PROPERTY_SUCCESS, + Messages.format(editedProperty)); + + Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), + new PropertyBook(), new UserPrefs()); + expectedModel.setProperty(lastProperty, editedProperty); + + assertCommandSuccess(editCommand, model, expectedMessage, expectedModel); + } + + @Test + public void execute_noFieldSpecifiedUnfilteredList_success() { + EditPropertyCommand editCommand = new EditPropertyCommand(INDEX_FIRST_PROPERTY, new EditPropertyDescriptor()); + Property editedProperty = model.getFilteredPropertyList().get(INDEX_FIRST_PROPERTY.getZeroBased()); + + String expectedMessage = String.format(EditPropertyCommand.MESSAGE_EDIT_PROPERTY_SUCCESS, + Messages.format(editedProperty)); + + Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), + new PropertyBook(), new UserPrefs()); + + assertCommandSuccess(editCommand, model, expectedMessage, expectedModel); + } + + @Test + public void execute_filteredList_success() { + showPropertyAtIndex(model, INDEX_FIRST_PROPERTY); + + Property propertyInFilteredList = model.getFilteredPropertyList().get(INDEX_FIRST_PROPERTY.getZeroBased()); + Property editedProperty = new PropertyBuilder(propertyInFilteredList).withName(VALID_NAME_SKYVIEW).build(); + EditPropertyCommand editCommand = new EditPropertyCommand(INDEX_FIRST_PROPERTY, + new EditPropertyDescriptorBuilder().withName(VALID_NAME_SKYVIEW).build()); + + String expectedMessage = String.format(EditPropertyCommand.MESSAGE_EDIT_PROPERTY_SUCCESS, + Messages.format(editedProperty)); + + Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), + new PropertyBook(), new UserPrefs()); + expectedModel.setProperty(model.getFilteredPropertyList().get(0), editedProperty); + + assertCommandSuccess(editCommand, model, expectedMessage, expectedModel); + } + + @Test + public void execute_duplicatePropertyUnfilteredList_failure() { + Property firstProperty = model.getFilteredPropertyList().get(INDEX_FIRST_PROPERTY.getZeroBased()); + EditPropertyDescriptor descriptor = new EditPropertyDescriptorBuilder(firstProperty).build(); + EditPropertyCommand editCommand = new EditPropertyCommand(INDEX_SECOND_PROPERTY, descriptor); + + assertCommandFailure(editCommand, model, EditPropertyCommand.MESSAGE_DUPLICATE_PROPERTY); + } + + @Test + public void execute_duplicatePropertyFilteredList_failure() { + showPropertyAtIndex(model, INDEX_FIRST_PROPERTY); + + // edit property in filtered list into a duplicate in budget book + Property propertyInList = model.getPropertyBook().getPropertyList().get(INDEX_SECOND_PROPERTY.getZeroBased()); + EditPropertyCommand editCommand = new EditPropertyCommand(INDEX_FIRST_PROPERTY, + new EditPropertyDescriptorBuilder(propertyInList).build()); + + assertCommandFailure(editCommand, model, EditPropertyCommand.MESSAGE_DUPLICATE_PROPERTY); + } + + @Test + public void execute_invalidPropertyIndexUnfilteredList_failure() { + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPropertyList().size() + 1); + EditPropertyDescriptor descriptor = new EditPropertyDescriptorBuilder().withName(VALID_NAME_SKYVIEW).build(); + EditPropertyCommand editCommand = new EditPropertyCommand(outOfBoundIndex, descriptor); + + assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_PROPERTY_DISPLAYED_INDEX); + } + + /** + * Edit filtered list where index is larger than size of filtered list, + * but smaller than size of budget book + */ + @Test + public void execute_invalidPropertyIndexFilteredList_failure() { + showPropertyAtIndex(model, INDEX_FIRST_PROPERTY); + Index outOfBoundIndex = INDEX_SECOND_PROPERTY; + // ensures that outOfBoundIndex is still in bounds of budget book list + assertTrue(outOfBoundIndex.getZeroBased() < model.getPropertyBook().getPropertyList().size()); + + EditPropertyCommand editCommand = new EditPropertyCommand(outOfBoundIndex, + new EditPropertyDescriptorBuilder().withName(VALID_NAME_SKYVIEW).build()); + + assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_PROPERTY_DISPLAYED_INDEX); + } + + @Test + public void equals() { + final EditPropertyCommand standardCommand = new EditPropertyCommand(INDEX_FIRST_PROPERTY, DESC_AQUAVIEW); + + // same values -> returns true + EditPropertyDescriptor copyDescriptor = new EditPropertyDescriptor(DESC_AQUAVIEW); + EditPropertyCommand commandWithSameValues = new EditPropertyCommand(INDEX_FIRST_PROPERTY, copyDescriptor); + 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 index -> returns false + assertFalse(standardCommand.equals(new EditPropertyCommand(INDEX_SECOND_PROPERTY, DESC_AQUAVIEW))); + + // different descriptor -> returns false + assertFalse(standardCommand.equals(new EditPropertyCommand(INDEX_FIRST_PROPERTY, DESC_SKYVIEW))); + } + + @Test + public void toStringMethod() { + Index index = Index.fromOneBased(1); + EditPropertyDescriptor editPropertyDescriptor = new EditPropertyDescriptor(); + EditPropertyCommand editCommand = new EditPropertyCommand(index, editPropertyDescriptor); + String expected = EditPropertyCommand.class.getCanonicalName() + "{index=" + index + ", editPropertyDescriptor=" + + editPropertyDescriptor + "}"; + assertEquals(expected, editCommand.toString()); + } + +} diff --git a/src/test/java/seedu/address/logic/commands/FindCommandTest.java b/src/test/java/seedu/address/logic/commands/FindCommandTest.java index a1b30ab0b6a..25f4b538a96 100644 --- a/src/test/java/seedu/address/logic/commands/FindCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/FindCommandTest.java @@ -9,6 +9,7 @@ import static seedu.address.testutil.TypicalCustomers.ELLE; import static seedu.address.testutil.TypicalCustomers.FIONA; import static seedu.address.testutil.TypicalCustomers.getTypicalAddressBook; +import static seedu.address.testutil.TypicalProperties.getTypicalPropertyBook; import java.util.Arrays; import java.util.Collections; @@ -17,7 +18,6 @@ import seedu.address.model.Model; import seedu.address.model.ModelManager; -import seedu.address.model.PropertyBook; import seedu.address.model.UserPrefs; import seedu.address.model.customer.NameContainsKeywordsPredicate; @@ -25,8 +25,8 @@ * Contains integration tests (interaction with the Model) for {@code FindCommand}. */ public class FindCommandTest { - private Model model = new ModelManager(getTypicalAddressBook(), new PropertyBook(), new UserPrefs()); - private Model expectedModel = new ModelManager(getTypicalAddressBook(), new PropertyBook(), new UserPrefs()); + private Model model = new ModelManager(getTypicalAddressBook(), getTypicalPropertyBook(), new UserPrefs()); + private Model expectedModel = new ModelManager(getTypicalAddressBook(), getTypicalPropertyBook(), new UserPrefs()); @Test public void equals() { diff --git a/src/test/java/seedu/address/logic/commands/ListCommandTest.java b/src/test/java/seedu/address/logic/commands/ListCommandTest.java index 51a0d0be400..2faa743340c 100644 --- a/src/test/java/seedu/address/logic/commands/ListCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ListCommandTest.java @@ -4,6 +4,7 @@ import static seedu.address.logic.commands.CommandTestUtil.showCustomerAtIndex; import static seedu.address.testutil.TypicalCustomers.getTypicalAddressBook; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_CUSTOMER; +import static seedu.address.testutil.TypicalProperties.getTypicalPropertyBook; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -23,7 +24,7 @@ public class ListCommandTest { @BeforeEach public void setUp() { - model = new ModelManager(getTypicalAddressBook(), new PropertyBook(), new UserPrefs()); + model = new ModelManager(getTypicalAddressBook(), getTypicalPropertyBook(), new UserPrefs()); expectedModel = new ModelManager(model.getAddressBook(), new PropertyBook(), new UserPrefs()); } diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 59699038857..1db740aad61 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -6,6 +6,7 @@ import static seedu.address.logic.Messages.MESSAGE_UNKNOWN_COMMAND; import static seedu.address.testutil.Assert.assertThrows; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_CUSTOMER; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PROPERTY; import java.util.Arrays; import java.util.List; @@ -17,7 +18,9 @@ import seedu.address.logic.commands.AddPropertyCommand; import seedu.address.logic.commands.ClearCommand; import seedu.address.logic.commands.DeleteCustomerCommand; +import seedu.address.logic.commands.DeletePropertyCommand; import seedu.address.logic.commands.EditCommand; +import seedu.address.logic.commands.EditPropertyCommand; import seedu.address.logic.commands.ExitCommand; import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.HelpCommand; @@ -29,6 +32,7 @@ import seedu.address.testutil.CustomerBuilder; import seedu.address.testutil.CustomerUtil; import seedu.address.testutil.EditCustomerDescriptorBuilder; +import seedu.address.testutil.EditPropertyDescriptorBuilder; import seedu.address.testutil.PropertyBuilder; import seedu.address.testutil.PropertyUtil; @@ -59,11 +63,17 @@ public void parseCommand_clear() throws Exception { @Test public void parseCommand_delcust() throws Exception { - DeleteCustomerCommand command = (DeleteCustomerCommand) parser.parseCommand( - DeleteCustomerCommand.COMMAND_WORD + " " + INDEX_FIRST_CUSTOMER.getOneBased()); - assertEquals(new DeleteCustomerCommand(INDEX_FIRST_CUSTOMER), command); + DeletePropertyCommand command = (DeletePropertyCommand) parser.parseCommand( + DeletePropertyCommand.COMMAND_WORD + " " + INDEX_FIRST_PROPERTY.getOneBased()); + assertEquals(new DeletePropertyCommand(INDEX_FIRST_PROPERTY), command); } + @Test + public void parseCommand_delprop() throws Exception { + DeleteCustomerCommand command = (DeleteCustomerCommand) parser.parseCommand( + DeleteCustomerCommand.COMMAND_WORD + " " + INDEX_FIRST_PROPERTY.getOneBased()); + assertEquals(new DeleteCustomerCommand(INDEX_FIRST_PROPERTY), command); + } @Test public void parseCommand_edit() throws Exception { Customer customer = new CustomerBuilder().build(); @@ -72,6 +82,14 @@ public void parseCommand_edit() throws Exception { + INDEX_FIRST_CUSTOMER.getOneBased() + " " + CustomerUtil.getEditCustomerDescriptorDetails(descriptor)); assertEquals(new EditCommand(INDEX_FIRST_CUSTOMER, descriptor), command); } + @Test + public void parseCommand_editprop() throws Exception { + Property property = new PropertyBuilder().build(); + EditPropertyCommand.EditPropertyDescriptor descriptor = new EditPropertyDescriptorBuilder(property).build(); + EditPropertyCommand command = (EditPropertyCommand) parser.parseCommand(EditPropertyCommand.COMMAND_WORD + " " + + INDEX_FIRST_PROPERTY.getOneBased() + " " + PropertyUtil.getEditPropertyDescriptorDetails(descriptor)); + assertEquals(new EditPropertyCommand(INDEX_FIRST_PROPERTY, descriptor), command); + } @Test public void parseCommand_exit() throws Exception { diff --git a/src/test/java/seedu/address/logic/parser/EditPropertyCommandParserTest.java b/src/test/java/seedu/address/logic/parser/EditPropertyCommandParserTest.java new file mode 100644 index 00000000000..edb4c51ee13 --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/EditPropertyCommandParserTest.java @@ -0,0 +1,208 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.commands.CommandPropertyTestUtil.ADDRESS_DESC_AQUAVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.ADDRESS_DESC_SKYVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.INVALID_ADDRESS_DESC; +import static seedu.address.logic.commands.CommandPropertyTestUtil.INVALID_NAME_DESC; +import static seedu.address.logic.commands.CommandPropertyTestUtil.INVALID_PHONE_DESC; +import static seedu.address.logic.commands.CommandPropertyTestUtil.INVALID_PRICE_DESC; +import static seedu.address.logic.commands.CommandPropertyTestUtil.INVALID_TAG_DESC; +import static seedu.address.logic.commands.CommandPropertyTestUtil.NAME_DESC_AQUAVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.PHONE_DESC_AQUAVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.PHONE_DESC_SKYVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.PRICE_DESC_AQUAVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.PRICE_DESC_SKYVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.TAG_DESC_BIG; +import static seedu.address.logic.commands.CommandPropertyTestUtil.TAG_DESC_SQUARE; +import static seedu.address.logic.commands.CommandPropertyTestUtil.VALID_ADDRESS_AQUAVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.VALID_NAME_AQUAVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.VALID_PHONE_AQUAVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.VALID_PHONE_SKYVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.VALID_PRICE_AQUAVIEW; +import static seedu.address.logic.commands.CommandPropertyTestUtil.VALID_TAG_BIG; +import static seedu.address.logic.commands.CommandPropertyTestUtil.VALID_TAG_SQUARE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PRICE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PROPERTY; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PROPERTY; +import static seedu.address.testutil.TypicalIndexes.INDEX_THIRD_PROPERTY; + +import org.junit.jupiter.api.Test; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.Messages; +import seedu.address.logic.commands.EditPropertyCommand; +import seedu.address.logic.commands.EditPropertyCommand.EditPropertyDescriptor; +import seedu.address.model.property.Price; +import seedu.address.model.property.PropAddress; +import seedu.address.model.property.PropName; +import seedu.address.model.property.PropPhone; +import seedu.address.model.tag.Tag; +import seedu.address.testutil.EditPropertyDescriptorBuilder; + +public class EditPropertyCommandParserTest { + + private static final String TAG_EMPTY = " " + PREFIX_TAG; + + private static final String MESSAGE_INVALID_FORMAT = + String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditPropertyCommand.MESSAGE_USAGE); + + private EditPropertyCommandParser parser = new EditPropertyCommandParser(); + + @Test + public void parse_missingParts_failure() { + // no index specified + assertParseFailure(parser, VALID_NAME_AQUAVIEW, MESSAGE_INVALID_FORMAT); + + // no field specified + assertParseFailure(parser, "1", EditPropertyCommand.MESSAGE_NOT_EDITED); + + // no index and no field specified + assertParseFailure(parser, "", MESSAGE_INVALID_FORMAT); + } + + @Test + public void parse_invalidPreamble_failure() { + // negative index + assertParseFailure(parser, "-5" + NAME_DESC_AQUAVIEW, MESSAGE_INVALID_FORMAT); + + // zero index + assertParseFailure(parser, "0" + NAME_DESC_AQUAVIEW, MESSAGE_INVALID_FORMAT); + + // invalid arguments being parsed as preamble + assertParseFailure(parser, "1 some random string", MESSAGE_INVALID_FORMAT); + + // invalid prefix being parsed as preamble + assertParseFailure(parser, "1 i/ string", MESSAGE_INVALID_FORMAT); + } + + @Test + public void parse_invalidValue_failure() { + assertParseFailure(parser, "1" + INVALID_NAME_DESC, PropName.MESSAGE_CONSTRAINTS); // invalid name + assertParseFailure(parser, "1" + INVALID_PHONE_DESC, PropPhone.MESSAGE_CONSTRAINTS); // invalid phone + assertParseFailure(parser, "1" + INVALID_ADDRESS_DESC, PropAddress.MESSAGE_CONSTRAINTS); // invalid address + assertParseFailure(parser, "1" + INVALID_PRICE_DESC, Price.MESSAGE_CONSTRAINTS); // invalid price + assertParseFailure(parser, "1" + INVALID_TAG_DESC, Tag.MESSAGE_CONSTRAINTS); // invalid tag + + // invalid phone followed by valid address + assertParseFailure(parser, "1" + INVALID_PHONE_DESC + ADDRESS_DESC_AQUAVIEW, PropPhone.MESSAGE_CONSTRAINTS); + + // while parsing {@code PREFIX_TAG} alone will reset the tags of the {@code Property} being edited, + // parsing it together with a valid tag results in error + assertParseFailure(parser, "1" + TAG_DESC_SQUARE + TAG_DESC_BIG + TAG_EMPTY, Tag.MESSAGE_CONSTRAINTS); + assertParseFailure(parser, "1" + TAG_DESC_SQUARE + TAG_EMPTY + TAG_DESC_BIG, Tag.MESSAGE_CONSTRAINTS); + assertParseFailure(parser, "1" + TAG_EMPTY + TAG_DESC_SQUARE + TAG_DESC_BIG, Tag.MESSAGE_CONSTRAINTS); + + // multiple invalid values, but only the first invalid value is captured + assertParseFailure(parser, "1" + INVALID_NAME_DESC + INVALID_ADDRESS_DESC + + VALID_PRICE_AQUAVIEW + VALID_PHONE_AQUAVIEW, PropName.MESSAGE_CONSTRAINTS); + } + + @Test + public void parse_allFieldsSpecified_success() { + Index targetIndex = INDEX_SECOND_PROPERTY; + String userInput = targetIndex.getOneBased() + PHONE_DESC_SKYVIEW + TAG_DESC_BIG + + ADDRESS_DESC_AQUAVIEW + PRICE_DESC_AQUAVIEW + NAME_DESC_AQUAVIEW + TAG_DESC_SQUARE; + + EditPropertyDescriptor descriptor = new EditPropertyDescriptorBuilder().withName(VALID_NAME_AQUAVIEW) + .withPhone(VALID_PHONE_SKYVIEW).withAddress(VALID_ADDRESS_AQUAVIEW).withPrice(VALID_PRICE_AQUAVIEW) + .withTags(VALID_TAG_BIG, VALID_TAG_SQUARE).build(); + EditPropertyCommand expectedCommand = new EditPropertyCommand(targetIndex, descriptor); + + assertParseSuccess(parser, userInput, expectedCommand); + } + + @Test + public void parse_someFieldsSpecified_success() { + Index targetIndex = INDEX_FIRST_PROPERTY; + String userInput = targetIndex.getOneBased() + PHONE_DESC_SKYVIEW + ADDRESS_DESC_AQUAVIEW; + + EditPropertyDescriptor descriptor = new EditPropertyDescriptorBuilder().withPhone(VALID_PHONE_SKYVIEW) + .withAddress(VALID_ADDRESS_AQUAVIEW).build(); + EditPropertyCommand expectedCommand = new EditPropertyCommand(targetIndex, descriptor); + + assertParseSuccess(parser, userInput, expectedCommand); + } + + @Test + public void parse_oneFieldSpecified_success() { + // name + Index targetIndex = INDEX_THIRD_PROPERTY; + String userInput = targetIndex.getOneBased() + NAME_DESC_AQUAVIEW; + EditPropertyDescriptor descriptor = new EditPropertyDescriptorBuilder().withName(VALID_NAME_AQUAVIEW).build(); + EditPropertyCommand expectedCommand = new EditPropertyCommand(targetIndex, descriptor); + assertParseSuccess(parser, userInput, expectedCommand); + + // phone + userInput = targetIndex.getOneBased() + PHONE_DESC_AQUAVIEW; + descriptor = new EditPropertyDescriptorBuilder().withPhone(VALID_PHONE_AQUAVIEW).build(); + expectedCommand = new EditPropertyCommand(targetIndex, descriptor); + assertParseSuccess(parser, userInput, expectedCommand); + + // ADDRESS + userInput = targetIndex.getOneBased() + ADDRESS_DESC_AQUAVIEW; + descriptor = new EditPropertyDescriptorBuilder().withAddress(VALID_ADDRESS_AQUAVIEW).build(); + expectedCommand = new EditPropertyCommand(targetIndex, descriptor); + assertParseSuccess(parser, userInput, expectedCommand); + + // PRICE + userInput = targetIndex.getOneBased() + PRICE_DESC_AQUAVIEW; + descriptor = new EditPropertyDescriptorBuilder().withPrice(VALID_PRICE_AQUAVIEW).build(); + expectedCommand = new EditPropertyCommand(targetIndex, descriptor); + assertParseSuccess(parser, userInput, expectedCommand); + + // tags + userInput = targetIndex.getOneBased() + TAG_DESC_SQUARE; + descriptor = new EditPropertyDescriptorBuilder().withTags(VALID_TAG_SQUARE).build(); + expectedCommand = new EditPropertyCommand(targetIndex, descriptor); + assertParseSuccess(parser, userInput, expectedCommand); + } + + @Test + public void parse_multipleRepeatedFields_failure() { + // More extensive testing of duplicate parameter detections is done in + // AddPropertyCommandParserTest#parse_repeatedNonTagValue_failure() + + // valid followed by invalid + Index targetIndex = INDEX_FIRST_PROPERTY; + String userInput = targetIndex.getOneBased() + INVALID_PHONE_DESC + PHONE_DESC_SKYVIEW; + + assertParseFailure(parser, userInput, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE)); + + // invalid followed by valid + userInput = targetIndex.getOneBased() + PHONE_DESC_SKYVIEW + INVALID_PHONE_DESC; + + assertParseFailure(parser, userInput, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE)); + + // mulltiple valid fields repeated + userInput = targetIndex.getOneBased() + PHONE_DESC_AQUAVIEW + PRICE_DESC_AQUAVIEW + ADDRESS_DESC_AQUAVIEW + + TAG_DESC_SQUARE + PHONE_DESC_AQUAVIEW + PRICE_DESC_AQUAVIEW + ADDRESS_DESC_AQUAVIEW + TAG_DESC_SQUARE + + PHONE_DESC_SKYVIEW + PRICE_DESC_SKYVIEW + ADDRESS_DESC_SKYVIEW + TAG_DESC_BIG; + + assertParseFailure(parser, userInput, + Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE, PREFIX_ADDRESS, PREFIX_PRICE)); + + // multiple invalid values + userInput = targetIndex.getOneBased() + INVALID_PHONE_DESC + INVALID_PRICE_DESC + INVALID_ADDRESS_DESC + + INVALID_PHONE_DESC + INVALID_PRICE_DESC + INVALID_ADDRESS_DESC; + + assertParseFailure(parser, userInput, + Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE, PREFIX_ADDRESS, PREFIX_PRICE)); + } + + @Test + public void parse_resetTags_success() { + Index targetIndex = INDEX_THIRD_PROPERTY; + String userInput = targetIndex.getOneBased() + TAG_EMPTY; + + EditPropertyDescriptor descriptor = new EditPropertyDescriptorBuilder().withTags().build(); + EditPropertyCommand expectedCommand = new EditPropertyCommand(targetIndex, descriptor); + + assertParseSuccess(parser, userInput, expectedCommand); + } +} diff --git a/src/test/java/seedu/address/model/AddressBookTest.java b/src/test/java/seedu/address/model/AddressBookTest.java index 809f8147b8e..3de974bea95 100644 --- a/src/test/java/seedu/address/model/AddressBookTest.java +++ b/src/test/java/seedu/address/model/AddressBookTest.java @@ -94,7 +94,6 @@ public void toStringMethod() { */ private static class AddressBookStub implements ReadOnlyAddressBook { private final ObservableList customers = FXCollections.observableArrayList(); - AddressBookStub(Collection customers) { this.customers.setAll(customers); } diff --git a/src/test/java/seedu/address/testutil/EditPropertyDescriptorBuilder.java b/src/test/java/seedu/address/testutil/EditPropertyDescriptorBuilder.java new file mode 100644 index 00000000000..6bc36bc4f09 --- /dev/null +++ b/src/test/java/seedu/address/testutil/EditPropertyDescriptorBuilder.java @@ -0,0 +1,87 @@ +package seedu.address.testutil; + +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import seedu.address.logic.commands.EditPropertyCommand.EditPropertyDescriptor; +import seedu.address.model.property.Price; +import seedu.address.model.property.PropAddress; +import seedu.address.model.property.PropName; +import seedu.address.model.property.PropPhone; +import seedu.address.model.property.Property; +import seedu.address.model.tag.Tag; + +/** + * A utility class to help with building EditpropertyDescriptor objects. + */ +public class EditPropertyDescriptorBuilder { + + private EditPropertyDescriptor descriptor; + + public EditPropertyDescriptorBuilder() { + descriptor = new EditPropertyDescriptor(); + } + + public EditPropertyDescriptorBuilder(EditPropertyDescriptor descriptor) { + this.descriptor = new EditPropertyDescriptor(descriptor); + } + + /** + * Returns an {@code EditpropertyDescriptor} with fields containing {@code property}'s details + */ + public EditPropertyDescriptorBuilder(Property property) { + descriptor = new EditPropertyDescriptor(); + descriptor.setName(property.getName()); + descriptor.setPhone(property.getPhone()); + descriptor.setAddress(property.getAddress()); + descriptor.setPrice(property.getPrice()); + descriptor.setTags(property.getTags()); + } + + /** + * Sets the {@code Name} of the {@code EditpropertyDescriptor} that we are building. + */ + public EditPropertyDescriptorBuilder withName(String name) { + descriptor.setName(new PropName(name)); + return this; + } + + /** + * Sets the {@code Phone} of the {@code EditpropertyDescriptor} that we are building. + */ + public EditPropertyDescriptorBuilder withPhone(String phone) { + descriptor.setPhone(new PropPhone(phone)); + return this; + } + + /** + * Sets the {@code Address} of the {@code EditpropertyDescriptor} that we are building. + */ + public EditPropertyDescriptorBuilder withAddress(String address) { + descriptor.setAddress(new PropAddress(address)); + return this; + } + + /** + * Sets the {@code Price} of the {@code EditpropertyDescriptor} that we are building. + */ + public EditPropertyDescriptorBuilder withPrice(String price) { + descriptor.setPrice(new Price(price)); + return this; + } + + /** + * Parses the {@code tags} into a {@code Set} and set it to the {@code EditpropertyDescriptor} + * that we are building. + */ + public EditPropertyDescriptorBuilder withTags(String... tags) { + Set tagSet = Stream.of(tags).map(Tag::new).collect(Collectors.toSet()); + descriptor.setTags(tagSet); + return this; + } + + public EditPropertyDescriptor build() { + return descriptor; + } +} diff --git a/src/test/java/seedu/address/testutil/PropertyUtil.java b/src/test/java/seedu/address/testutil/PropertyUtil.java index ab9dc08e09c..d21cafa654f 100644 --- a/src/test/java/seedu/address/testutil/PropertyUtil.java +++ b/src/test/java/seedu/address/testutil/PropertyUtil.java @@ -1,13 +1,19 @@ package seedu.address.testutil; -import static seedu.address.logic.parser.CliSyntax.PREFIX_BUDGET; -import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PRICE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import java.util.Set; + import seedu.address.logic.commands.AddPropertyCommand; +import seedu.address.logic.commands.EditPropertyCommand; import seedu.address.model.property.Property; +import seedu.address.model.tag.Tag; + + /** * A utility class for Property. @@ -28,11 +34,30 @@ public static String getPropertyDetails(Property property) { StringBuilder sb = new StringBuilder(); sb.append(PREFIX_NAME + property.getName().fullName + " "); sb.append(PREFIX_PHONE + property.getPhone().value + " "); - sb.append(PREFIX_EMAIL + property.getAddress().value + " "); - sb.append(PREFIX_BUDGET + property.getPrice().value + " "); + sb.append(PREFIX_ADDRESS + property.getAddress().value + " "); + sb.append(PREFIX_PRICE + property.getPrice().value + " "); property.getTags().stream().forEach( s -> sb.append(PREFIX_TAG + s.tagName + " ") ); return sb.toString(); } + /** + * Returns the part of command string for the given {@code EditPropertyDescriptor}'s details. + */ + public static String getEditPropertyDescriptorDetails(EditPropertyCommand.EditPropertyDescriptor descriptor) { + StringBuilder sb = new StringBuilder(); + descriptor.getName().ifPresent(name -> sb.append(PREFIX_NAME).append(name.fullName).append(" ")); + descriptor.getPhone().ifPresent(phone -> sb.append(PREFIX_PHONE).append(phone.value).append(" ")); + descriptor.getAddress().ifPresent(address -> sb.append(PREFIX_ADDRESS).append(address.value).append(" ")); + descriptor.getPrice().ifPresent(price -> sb.append(PREFIX_PRICE).append(price.value).append(" ")); + if (descriptor.getTags().isPresent()) { + Set tags = descriptor.getTags().get(); + if (tags.isEmpty()) { + sb.append(PREFIX_TAG); + } else { + tags.forEach(s -> sb.append(PREFIX_TAG).append(s.tagName).append(" ")); + } + } + return sb.toString(); + } }