diff --git a/src/main/java/seedu/address/logic/commands/AddNoteCommand.java b/src/main/java/seedu/address/logic/commands/AddNoteCommand.java index 1ad4d7b83f2..9f78791a71f 100644 --- a/src/main/java/seedu/address/logic/commands/AddNoteCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddNoteCommand.java @@ -2,6 +2,7 @@ import static java.util.Objects.requireNonNull; +import seedu.address.commons.util.ToStringBuilder; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; import seedu.address.model.note.Note; @@ -42,4 +43,30 @@ public CommandResult execute(Model model) throws CommandException { return new CommandResult(MESSAGE_SUCCESS + toAdd.getTitle()); } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof AddNoteCommand)) { + return false; + } + + AddNoteCommand otherAddNoteCommand = (AddNoteCommand) other; + + boolean equalToAdd = toAdd.equals(otherAddNoteCommand.toAdd); + boolean equalContactId = (contactId == otherAddNoteCommand.contactId); + return equalToAdd && equalContactId; + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("toAdd", toAdd) + .add("contactId", contactId) + .toString(); + } } diff --git a/src/main/java/seedu/address/logic/commands/DeleteNoteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteNoteCommand.java index 298c9493f8a..09a5a69d0f6 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteNoteCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteNoteCommand.java @@ -2,6 +2,7 @@ import static java.util.Objects.requireNonNull; +import seedu.address.commons.util.ToStringBuilder; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; import seedu.address.model.person.Person; @@ -42,4 +43,30 @@ public CommandResult execute(Model model) throws CommandException { return new CommandResult(MESSAGE_SUCCESS + this.noteIdToDelete); } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof DeleteNoteCommand)) { + return false; + } + + DeleteNoteCommand otherDeleteNoteCommand = (DeleteNoteCommand) other; + + boolean equalNoteIdToDelete = (noteIdToDelete == otherDeleteNoteCommand.noteIdToDelete); + boolean equalContactId = (contactId == otherDeleteNoteCommand.contactId); + return equalNoteIdToDelete && equalContactId; + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("noteIdToDelete", noteIdToDelete) + .add("contactId", contactId) + .toString(); + } } diff --git a/src/main/java/seedu/address/model/note/Note.java b/src/main/java/seedu/address/model/note/Note.java index bef49806269..7d8378e3fe1 100644 --- a/src/main/java/seedu/address/model/note/Note.java +++ b/src/main/java/seedu/address/model/note/Note.java @@ -41,4 +41,24 @@ public String getUiText() { String result = this.getTitle() + " (content: " + this.getContent() + ")"; return result; } + + /** + * Returns true if both notes have the same identity and data fields. + * This defines a stronger notion of equality between two notes. + */ + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof Note)) { + return false; + } + + Note otherNote = (Note) other; + return title.equals(otherNote.title) + && content.equals(otherNote.content); + } } diff --git a/src/main/java/seedu/address/model/note/NoteContent.java b/src/main/java/seedu/address/model/note/NoteContent.java index 530623e0d51..0f1238f329d 100644 --- a/src/main/java/seedu/address/model/note/NoteContent.java +++ b/src/main/java/seedu/address/model/note/NoteContent.java @@ -18,6 +18,21 @@ public static NoteContent fromString(String content) { return new NoteContent(content); } + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof NoteContent)) { + return false; + } + + NoteContent otherNoteContent = (NoteContent) other; + return content.equals(otherNoteContent.content); + } + @Override public String toString() { return this.content; diff --git a/src/main/java/seedu/address/model/note/NoteTitle.java b/src/main/java/seedu/address/model/note/NoteTitle.java index 5564d1066bd..d3e233c4918 100644 --- a/src/main/java/seedu/address/model/note/NoteTitle.java +++ b/src/main/java/seedu/address/model/note/NoteTitle.java @@ -18,6 +18,21 @@ public static NoteTitle fromString(String title) { return new NoteTitle(title); } + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof NoteTitle)) { + return false; + } + + NoteTitle otherNoteTitle = (NoteTitle) other; + return title.equals(otherNoteTitle.title); + } + @Override public String toString() { return this.title; diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java index 643a1d08069..5c7f59cefd7 100644 --- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java +++ b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java @@ -5,6 +5,10 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTE_CONTENT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTE_ID; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTE_TITLE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PERSON_ID; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import static seedu.address.testutil.Assert.assertThrows; @@ -36,6 +40,14 @@ public class CommandTestUtil { public static final String VALID_ADDRESS_BOB = "Block 123, Bobby Street 3"; public static final String VALID_TAG_HUSBAND = "husband"; public static final String VALID_TAG_FRIEND = "friend"; + public static final String VALID_NOTE_A_PERSON_ID = "1"; + public static final String VALID_NOTE_A_TITLE = "Preferred Qualifications"; + public static final String VALID_NOTE_A_CONTENT = "Machine Learning Frameworks"; + public static final String VALID_NOTE_A_NOTE_ID = "1"; + public static final String VALID_NOTE_B_PERSON_ID = "2"; + public static final String VALID_NOTE_B_TITLE = "Preferred Major"; + public static final String VALID_NOTE_B_CONTENT = "Computer Science"; + public static final String VALID_NOTE_B_NOTE_ID = "1"; public static final String NAME_DESC_AMY = " " + PREFIX_NAME + VALID_NAME_AMY; public static final String NAME_DESC_BOB = " " + PREFIX_NAME + VALID_NAME_BOB; @@ -47,6 +59,14 @@ public class CommandTestUtil { public static final String ADDRESS_DESC_BOB = " " + PREFIX_ADDRESS + VALID_ADDRESS_BOB; public static final String TAG_DESC_FRIEND = " " + PREFIX_TAG + VALID_TAG_FRIEND; public static final String TAG_DESC_HUSBAND = " " + PREFIX_TAG + VALID_TAG_HUSBAND; + public static final String NOTE_A_PERSON_ID_DESC = " " + PREFIX_PERSON_ID + VALID_NOTE_A_PERSON_ID; + public static final String NOTE_A_TITLE_DESC = " " + PREFIX_NOTE_TITLE + VALID_NOTE_A_TITLE; + public static final String NOTE_A_CONTENT_DESC = " " + PREFIX_NOTE_CONTENT + VALID_NOTE_A_CONTENT; + public static final String NOTE_A_NOTE_ID_DESC = " " + PREFIX_NOTE_ID + VALID_NOTE_A_NOTE_ID; + public static final String NOTE_B_PERSON_ID_DESC = " " + PREFIX_PERSON_ID + VALID_NOTE_B_PERSON_ID; + public static final String NOTE_B_TITLE_DESC = " " + PREFIX_NOTE_TITLE + VALID_NOTE_B_TITLE; + public static final String NOTE_B_CONTENT_DESC = " " + PREFIX_NOTE_CONTENT + VALID_NOTE_B_CONTENT; + public static final String NOTE_B_NOTE_ID_DESC = " " + PREFIX_NOTE_ID + VALID_NOTE_B_NOTE_ID; public static final String INVALID_NAME_DESC = " " + PREFIX_NAME + "James&"; // '&' not allowed in names public static final String INVALID_PHONE_DESC = " " + PREFIX_PHONE + "911a"; // 'a' not allowed in phones diff --git a/src/test/java/seedu/address/logic/parser/AddNoteCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddNoteCommandParserTest.java new file mode 100644 index 00000000000..0057df79276 --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/AddNoteCommandParserTest.java @@ -0,0 +1,83 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.commands.CommandTestUtil.NOTE_A_CONTENT_DESC; +import static seedu.address.logic.commands.CommandTestUtil.NOTE_A_PERSON_ID_DESC; +import static seedu.address.logic.commands.CommandTestUtil.NOTE_A_TITLE_DESC; +import static seedu.address.logic.commands.CommandTestUtil.NOTE_B_CONTENT_DESC; +import static seedu.address.logic.commands.CommandTestUtil.NOTE_B_PERSON_ID_DESC; +import static seedu.address.logic.commands.CommandTestUtil.NOTE_B_TITLE_DESC; +import static seedu.address.logic.commands.CommandTestUtil.PREAMBLE_WHITESPACE; +import static seedu.address.logic.commands.CommandTestUtil.VALID_NOTE_A_CONTENT; +import static seedu.address.logic.commands.CommandTestUtil.VALID_NOTE_A_PERSON_ID; +import static seedu.address.logic.commands.CommandTestUtil.VALID_NOTE_A_TITLE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTE_CONTENT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTE_TITLE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PERSON_ID; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; +import static seedu.address.testutil.TypicalNotes.NOTE_A; + +import org.junit.jupiter.api.Test; + +import seedu.address.logic.Messages; +import seedu.address.logic.commands.AddNoteCommand; +import seedu.address.model.note.Note; + +public class AddNoteCommandParserTest { + private AddNoteCommandParser parser = new AddNoteCommandParser(); + + @Test + public void parse_allFieldsPresent_success() { + Note expectedNote = NOTE_A; + + // whitespace only preamble + assertParseSuccess(parser, PREAMBLE_WHITESPACE + NOTE_A_PERSON_ID_DESC + NOTE_A_TITLE_DESC + + NOTE_A_CONTENT_DESC, + new AddNoteCommand(Integer.parseInt(VALID_NOTE_A_PERSON_ID), expectedNote)); + } + + @Test + public void parse_repeatedNonTagValue_failure() { + String validExpectedNoteString = NOTE_B_PERSON_ID_DESC + NOTE_B_TITLE_DESC + NOTE_B_CONTENT_DESC; + + // multiple person ids + assertParseFailure(parser, NOTE_A_PERSON_ID_DESC + validExpectedNoteString, + Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PERSON_ID)); + + // multiple titles + assertParseFailure(parser, NOTE_A_TITLE_DESC + validExpectedNoteString, + Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NOTE_TITLE)); + + // multiple contents + assertParseFailure(parser, NOTE_A_CONTENT_DESC + validExpectedNoteString, + Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NOTE_CONTENT)); + + // multiple fields repeated + assertParseFailure(parser, + validExpectedNoteString + NOTE_A_PERSON_ID_DESC + NOTE_A_TITLE_DESC + NOTE_A_CONTENT_DESC + + validExpectedNoteString, + Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PERSON_ID, PREFIX_NOTE_TITLE, PREFIX_NOTE_CONTENT)); + } + + @Test + public void parse_compulsoryFieldMissing_failure() { + String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddNoteCommand.MESSAGE_USAGE); + + // missing person id prefix + assertParseFailure(parser, VALID_NOTE_A_PERSON_ID + NOTE_A_TITLE_DESC + NOTE_A_CONTENT_DESC, + expectedMessage); + + // missing title prefix + assertParseFailure(parser, NOTE_A_PERSON_ID_DESC + VALID_NOTE_A_TITLE + NOTE_A_CONTENT_DESC, + expectedMessage); + + // missing content prefix + assertParseFailure(parser, NOTE_A_PERSON_ID_DESC + NOTE_A_TITLE_DESC + VALID_NOTE_A_CONTENT, + expectedMessage); + + // all prefixes missing + assertParseFailure(parser, VALID_NOTE_A_PERSON_ID + VALID_NOTE_A_TITLE + VALID_NOTE_A_CONTENT, + expectedMessage); + } +} diff --git a/src/test/java/seedu/address/logic/parser/DeleteNoteCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteNoteCommandParserTest.java new file mode 100644 index 00000000000..0c5582843b5 --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/DeleteNoteCommandParserTest.java @@ -0,0 +1,67 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.commands.CommandTestUtil.NOTE_A_NOTE_ID_DESC; +import static seedu.address.logic.commands.CommandTestUtil.NOTE_A_PERSON_ID_DESC; +import static seedu.address.logic.commands.CommandTestUtil.NOTE_B_NOTE_ID_DESC; +import static seedu.address.logic.commands.CommandTestUtil.NOTE_B_PERSON_ID_DESC; +import static seedu.address.logic.commands.CommandTestUtil.PREAMBLE_WHITESPACE; +import static seedu.address.logic.commands.CommandTestUtil.VALID_NOTE_A_NOTE_ID; +import static seedu.address.logic.commands.CommandTestUtil.VALID_NOTE_A_PERSON_ID; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTE_ID; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PERSON_ID; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; + +import org.junit.jupiter.api.Test; + +import seedu.address.logic.Messages; +import seedu.address.logic.commands.DeleteNoteCommand; + +public class DeleteNoteCommandParserTest { + private DeleteNoteCommandParser parser = new DeleteNoteCommandParser(); + + @Test + public void parse_allFieldsPresent_success() { + // whitespace only preamble + assertParseSuccess(parser, PREAMBLE_WHITESPACE + NOTE_A_PERSON_ID_DESC + NOTE_A_NOTE_ID_DESC, + new DeleteNoteCommand(Integer.parseInt(VALID_NOTE_A_PERSON_ID), + Integer.parseInt(VALID_NOTE_A_NOTE_ID))); + } + + @Test + public void parse_repeatedNonTagValue_failure() { + String validExpectedNoteString = NOTE_B_PERSON_ID_DESC + NOTE_B_NOTE_ID_DESC; + + // multiple person ids + assertParseFailure(parser, NOTE_A_PERSON_ID_DESC + validExpectedNoteString, + Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PERSON_ID)); + + // multiple note ids + assertParseFailure(parser, NOTE_A_NOTE_ID_DESC + validExpectedNoteString, + Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NOTE_ID)); + + // multiple fields repeated + assertParseFailure(parser, + validExpectedNoteString + NOTE_A_PERSON_ID_DESC + NOTE_A_NOTE_ID_DESC + + validExpectedNoteString, + Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PERSON_ID, PREFIX_NOTE_ID)); + } + + @Test + public void parse_compulsoryFieldMissing_failure() { + String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteNoteCommand.MESSAGE_USAGE); + + // missing person id prefix + assertParseFailure(parser, VALID_NOTE_A_PERSON_ID + NOTE_A_NOTE_ID_DESC, + expectedMessage); + + // missing note id prefix + assertParseFailure(parser, NOTE_A_PERSON_ID_DESC + VALID_NOTE_A_NOTE_ID, + expectedMessage); + + // all prefixes missing + assertParseFailure(parser, VALID_NOTE_A_PERSON_ID + VALID_NOTE_A_NOTE_ID, + expectedMessage); + } +} diff --git a/src/test/java/seedu/address/model/note/NoteContentTest.java b/src/test/java/seedu/address/model/note/NoteContentTest.java new file mode 100644 index 00000000000..b7a046bb48c --- /dev/null +++ b/src/test/java/seedu/address/model/note/NoteContentTest.java @@ -0,0 +1,28 @@ +package seedu.address.model.note; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class NoteContentTest { + @Test + public void equals() { + NoteContent content = NoteContent.fromString("Valid Note Content"); + + // same values -> returns true + assertTrue(content.equals(NoteContent.fromString("Valid Note Content"))); + + // same object -> returns true + assertTrue(content.equals(content)); + + // null -> returns false + assertFalse(content.equals(null)); + + // different types -> returns false + assertFalse(content.equals(5.0f)); + + // different values -> returns false + assertFalse(content.equals(NoteContent.fromString("Other Valid Note Content"))); + } +} diff --git a/src/test/java/seedu/address/model/note/NoteTest.java b/src/test/java/seedu/address/model/note/NoteTest.java new file mode 100644 index 00000000000..4b4420692b6 --- /dev/null +++ b/src/test/java/seedu/address/model/note/NoteTest.java @@ -0,0 +1,41 @@ +package seedu.address.model.note; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.address.logic.commands.CommandTestUtil.VALID_NOTE_B_CONTENT; +import static seedu.address.logic.commands.CommandTestUtil.VALID_NOTE_B_TITLE; +import static seedu.address.testutil.TypicalNotes.NOTE_A; +import static seedu.address.testutil.TypicalNotes.NOTE_B; + +import org.junit.jupiter.api.Test; + +import seedu.address.testutil.NoteBuilder; + +public class NoteTest { + @Test + public void equals() { + // same values -> returns true + Note noteACopy = new NoteBuilder(NOTE_A).build(); + assertTrue(NOTE_A.equals(noteACopy)); + + // same object -> returns true + assertTrue(NOTE_A.equals(NOTE_A)); + + // null -> returns false + assertFalse(NOTE_A.equals(null)); + + // different type -> returns false + assertFalse(NOTE_A.equals(5)); + + // different note -> returns false + assertFalse(NOTE_A.equals(NOTE_B)); + + // different title -> returns false + Note editedNoteA = new NoteBuilder(NOTE_A).withTitle(VALID_NOTE_B_TITLE).build(); + assertFalse(NOTE_A.equals(editedNoteA)); + + // different content -> returns false + editedNoteA = new NoteBuilder(NOTE_A).withContent(VALID_NOTE_B_CONTENT).build(); + assertFalse(NOTE_A.equals(editedNoteA)); + } +} diff --git a/src/test/java/seedu/address/model/note/NoteTitleTest.java b/src/test/java/seedu/address/model/note/NoteTitleTest.java new file mode 100644 index 00000000000..49896db0bf9 --- /dev/null +++ b/src/test/java/seedu/address/model/note/NoteTitleTest.java @@ -0,0 +1,28 @@ +package seedu.address.model.note; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class NoteTitleTest { + @Test + public void equals() { + NoteTitle title = NoteTitle.fromString("Valid Note Title"); + + // same values -> returns true + assertTrue(title.equals(NoteTitle.fromString("Valid Note Title"))); + + // same object -> returns true + assertTrue(title.equals(title)); + + // null -> returns false + assertFalse(title.equals(null)); + + // different types -> returns false + assertFalse(title.equals(5.0f)); + + // different values -> returns false + assertFalse(title.equals(NoteTitle.fromString("Other Valid Note Title"))); + } +} diff --git a/src/test/java/seedu/address/testutil/NoteBuilder.java b/src/test/java/seedu/address/testutil/NoteBuilder.java new file mode 100644 index 00000000000..b08b4925130 --- /dev/null +++ b/src/test/java/seedu/address/testutil/NoteBuilder.java @@ -0,0 +1,52 @@ +package seedu.address.testutil; + +import seedu.address.model.note.Note; +import seedu.address.model.note.NoteContent; +import seedu.address.model.note.NoteTitle; + +/** + * A utility class to help with building Note objects. + */ +public class NoteBuilder { + public static final String DEFAULT_TITLE = "Labrador Park"; + public static final String DEFAULT_CONTENT = "Forgot to take picture"; + + private NoteTitle title; + private NoteContent content; + + /** + * Creates a {@code NoteBuilder} with the default details. + */ + public NoteBuilder() { + title = NoteTitle.fromString(DEFAULT_TITLE); + content = NoteContent.fromString(DEFAULT_CONTENT); + } + + /** + * Initializes the NoteBuilder with the data of {@code noteToCopy}. + */ + public NoteBuilder(Note noteToCopy) { + title = NoteTitle.fromString(noteToCopy.getTitle()); + content = NoteContent.fromString(noteToCopy.getContent()); + } + + /** + * Sets the {@code Title} of the {@code Note} that we are building. + */ + public NoteBuilder withTitle(String title) { + this.title = NoteTitle.fromString(title); + return this; + } + + /** + * Sets the {@code Content} of the {@code Note} that we are building. + */ + public NoteBuilder withContent(String content) { + this.content = NoteContent.fromString(content); + return this; + } + + public Note build() { + return new Note(title.toString(), content.toString()); + } +} diff --git a/src/test/java/seedu/address/testutil/TypicalNotes.java b/src/test/java/seedu/address/testutil/TypicalNotes.java new file mode 100644 index 00000000000..75cfc4b2bda --- /dev/null +++ b/src/test/java/seedu/address/testutil/TypicalNotes.java @@ -0,0 +1,23 @@ +package seedu.address.testutil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import seedu.address.model.note.Note; + +/** + * A utility class containing a list of {@code Note} objects to be used in tests. + */ +public class TypicalNotes { + public static final Note NOTE_A = new NoteBuilder().withTitle("Preferred Qualifications") + .withContent("Machine Learning Frameworks").build(); + public static final Note NOTE_B = new NoteBuilder().withTitle("Preferred Major") + .withContent("Computer Science").build(); + + private TypicalNotes() {} // prevents instantiation + + public static List getTypicalNotes() { + return new ArrayList<>(Arrays.asList(NOTE_A, NOTE_B)); + } +}