diff --git a/README.md b/README.md
index 16208adb9b6..cacd2ff07f7 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,24 @@
-[](https://github.com/se-edu/addressbook-level3/actions)
+[](https://codecov.io/gh/AY2425S2-CS2103T-F13-3/tp)

-* This is **a sample project for Software Engineering (SE) students**.
- Example usages:
- * as a starting point of a course project (as opposed to writing everything from scratch)
- * as a case study
-* The project simulates an ongoing software project for a desktop application (called _AddressBook_) used for managing contact details.
- * It is **written in OOP fashion**. It provides a **reasonably well-written** code base **bigger** (around 6 KLoC) than what students usually write in beginner-level SE modules, without being overwhelmingly big.
- * It comes with a **reasonable level of user and developer documentation**.
-* It is named `AddressBook Level 3` (`AB3` for short) because it was initially created as a part of a series of `AddressBook` projects (`Level 1`, `Level 2`, `Level 3` ...).
-* For the detailed documentation of this project, see the **[Address Book Product Website](https://se-education.org/addressbook-level3)**.
-* This project is a **part of the se-education.org** initiative. If you would like to contribute code to this project, see [se-education.org](https://se-education.org/#contributing-to-se-edu) for more info.
+## Overview
+HireHive is a desktop application designed for small companies to efficiently track job candidates, manage interview notes, and streamline the hiring process.
+
+**Target users:** HR and recruitment managers for companies.
+
+### **Key Features**
+- **Track Interview Stages & Notes** – Keep detailed records of interviews and past communications.
+- **Bookmark Potential Candidates** – Mark standout applicants for future consideration.
+- **Categorize Candidates** – Filter candidates by job role and recruitment stage.
+
+### Running our application:
+1. Download our latest release (.jar or executable file).
+2. In your terminal, run ```java -jar HireHive.jar```
+3. Enjoy :)
+
+For the detailed documentation of this project, see the [HireHive Product Website](https://github.com/AY2425S2-CS2103T-F13-3/tp)
+This project is based on the AddressBook-Level3 project created by the [SE-EDU initiative](https://se-education.org).
+This project is a part of the se-education.org initiative. If you would like to contribute code to this project, see [se-education.org](https://se-education.org/#contributing-to-se-edu) for more info.
+
+
diff --git a/build.gradle b/build.gradle
index 0db3743584e..1b1c104befb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ plugins {
id 'jacoco'
}
-mainClassName = 'seedu.address.Main'
+mainClassName = 'hirehive.address.Main'
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
@@ -20,6 +20,10 @@ checkstyle {
toolVersion = '10.2'
}
+run {
+ enableAssertions = true
+}
+
test {
useJUnitPlatform()
finalizedBy jacocoTestReport
@@ -66,7 +70,7 @@ dependencies {
}
shadowJar {
- archiveFileName = 'addressbook.jar'
+ archiveFileName = 'HireHive.jar'
}
defaultTasks 'clean', 'test'
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
index eb761a9b9a7..35888555cbf 100644
--- a/config/checkstyle/checkstyle.xml
+++ b/config/checkstyle/checkstyle.xml
@@ -30,8 +30,8 @@
-
-
+
+
@@ -75,7 +75,7 @@
An import statement is unused if:
It's not referenced in the file.
-->
-
+
diff --git a/docs/AboutUs.md b/docs/AboutUs.md
index ff3f04abd02..f232e8283e8 100644
--- a/docs/AboutUs.md
+++ b/docs/AboutUs.md
@@ -9,51 +9,50 @@ You can reach us at the email `seer[at]comp.nus.edu.sg`
## Project team
-### John Doe
+### Wong Zenwei
-
+
-[[homepage](http://www.comp.nus.edu.sg/~damithch)]
-[[github](https://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](https://github.com/zeotheburrito)]
+[[portfolio](team/zeotheburrito.md)]
* Role: Project Advisor
-### Jane Doe
+### Lam Yun Hong
-
+
-[[github](http://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](https://github.com/m0destly)]
+[[portfolio](team/m0destly.md)]
-* Role: Team Lead
-* Responsibilities: UI
+* Role: Team Member
+* Responsibilities: Help the team
-### Johnny Doe
+### Natalie Ong
-
+
-[[github](http://github.com/johndoe)] [[portfolio](team/johndoe.md)]
+[[github](http://github.com/nat-ong555)] [[portfolio](team/nat-ong555.md)]
* Role: Developer
-* Responsibilities: Data
+* Responsibilities: Data, Documentation
-### Jean Doe
+### Deanna Poh
-
+
-[[github](http://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](http://github.com/deannapoh)]
+[[portfolio](team/deannapoh.md)]
* Role: Developer
-* Responsibilities: Dev Ops + Threading
+* Responsibilities: UI/UX
-### James Doe
+### Caleb Cherng
-
+
-[[github](http://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](http://github.com/ditzchann)]
+[[portfolio](team/ditzchann.md)]
* Role: Developer
-* Responsibilities: UI
+* Responsibilities: Testing, Code Quality
diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md
index 743c65a49d2..e1548a86eb0 100644
--- a/docs/DeveloperGuide.md
+++ b/docs/DeveloperGuide.md
@@ -9,7 +9,7 @@ title: Developer Guide
## **Acknowledgements**
-* {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well}
+* This project is based on the AddressBook-Level3 project created by the [SE-EDU initiative](https://se-education.org).
--------------------------------------------------------------------------------------------------------------------
@@ -21,6 +21,12 @@ Refer to the guide [_Setting up and getting started_](SettingUp.md).
## **Design**
+
+
+**:information_source: Note:**
+* Note that the class names with the name `AddressBook` are intentionally left as it is as our classes are named as such
+
+
:bulb: **Tip:** The `.puml` files used to create diagrams in this document `docs/diagrams` folder. Refer to the [_PlantUML Tutorial_ at se-edu/guides](https://se-education.org/guides/tutorials/plantUml.html) to learn how to create and edit diagrams.
@@ -36,7 +42,7 @@ Given below is a quick overview of main components and how they interact with ea
**Main components of the architecture**
-**`Main`** (consisting of classes [`Main`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/Main.java) and [`MainApp`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/MainApp.java)) is in charge of the app launch and shut down.
+**`Main`** (consisting of classes [`Main`](https://github.com/AY2425S2-CS2103T-F13-3/tp/blob/master/src/main/java/hirehive/address/Main.java) and [`MainApp`](https://github.com/AY2425S2-CS2103T-F13-3/tp/blob/master/src/main/java/hirehive/address/MainApp.java)) is in charge of the app launch and shut down.
* At app launch, it initializes the other components in the correct sequence, and connects them up with each other.
* At shut down, it shuts down the other components and invokes cleanup methods where necessary.
@@ -51,9 +57,9 @@ The bulk of the app's work is done by the following four components:
**How the architecture components interact with each other**
-The *Sequence Diagram* below shows how the components interact with each other for the scenario where the user issues the command `delete 1`.
+The *Sequence Diagram* below shows how the components interact with each other for the scenario where the user issues the command `delete n/Alice`.
-
+
Each of the four main components (also shown in the diagram above),
@@ -68,13 +74,13 @@ The sections below give more details of each component.
### UI component
-The **API** of this component is specified in [`Ui.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/Ui.java)
+The **API** of this component is specified in [`Ui.java`](https://github.com/AY2425S2-CS2103T-F13-3/tp/blob/master/src/main/java/hirehive/address/ui/Ui.java)

The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `PersonListPanel`, `StatusBarFooter` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class which captures the commonalities between classes that represent parts of the visible GUI.
-The `UI` component uses the JavaFx UI framework. The layout of these UI parts are defined in matching `.fxml` files that are in the `src/main/resources/view` folder. For example, the layout of the [`MainWindow`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/MainWindow.java) is specified in [`MainWindow.fxml`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/resources/view/MainWindow.fxml)
+The `UI` component uses the JavaFx UI framework. The layout of these UI parts are defined in matching `.fxml` files that are in the `src/main/resources/view` folder. For example, the layout of the [`MainWindow`](https://github.com/AY2425S2-CS2103T-F13-3/tp/blob/master/src/main/java/hirehive/address/ui/MainWindow.java) is specified in [`MainWindow.fxml`](https://github.com/AY2425S2-CS2103T-F13-3/tp/blob/master/src/main/resources/view/MainWindow.fxml)
The `UI` component,
@@ -85,15 +91,15 @@ The `UI` component,
### Logic component
-**API** : [`Logic.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/logic/Logic.java)
+**API** : [`Logic.java`](https://github.com/AY2425S2-CS2103T-F13-3/tp/blob/master/src/main/java/hirehive/address/logic/Logic.java)
Here's a (partial) class diagram of the `Logic` component:
-The sequence diagram below illustrates the interactions within the `Logic` component, taking `execute("delete 1")` API call as an example.
+The sequence diagram below illustrates the interactions within the `Logic` component, taking `execute("delete n/Alice")` API call as an example.
-
+
:information_source: **Note:** The lifeline for `DeleteCommandParser` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline continues till the end of diagram.
@@ -115,7 +121,7 @@ How the parsing works:
* All `XYZCommandParser` classes (e.g., `AddCommandParser`, `DeleteCommandParser`, ...) inherit from the `Parser` interface so that they can be treated similarly where possible e.g, during testing.
### Model component
-**API** : [`Model.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/model/Model.java)
+**API** : [`Model.java`](https://github.com/AY2425S2-CS2103T-F13-3/tp/blob/master/src/main/java/hirehive/address/model/Model.java)
@@ -136,7 +142,7 @@ The `Model` component,
### Storage component
-**API** : [`Storage.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/storage/Storage.java)
+**API** : [`Storage.java`](https://github.com/AY2425S2-CS2103T-F13-3/tp/blob/master/src/main/java/hirehive/address/storage/Storage.java)
@@ -192,7 +198,7 @@ Step 4. The user now decides that adding the person was a mistake, and decides t
:information_source: **Note:** If the `currentStatePointer` is at index 0, pointing to the initial AddressBook state, then there are no previous AddressBook states to restore. The `undo` command uses `Model#canUndoAddressBook()` to check if this is the case. If so, it will return an error to the user rather
than attempting to perform the undo.
-
+
z
The following sequence diagram shows how an undo operation goes through the `Logic` component:
@@ -237,13 +243,6 @@ The following activity diagram summarizes what happens when a user executes a ne
* Pros: Will use less memory (e.g. for `delete`, just save the person being deleted).
* Cons: We must ensure that the implementation of each individual command are correct.
-_{more aspects and alternatives to be added}_
-
-### \[Proposed\] Data archiving
-
-_{Explain here how the data archiving feature will be implemented}_
-
-
--------------------------------------------------------------------------------------------------------------------
## **Documentation, logging, testing, configuration, dev-ops**
@@ -260,7 +259,9 @@ _{Explain here how the data archiving feature will be implemented}_
### Product scope
-**Target user profile**:
+**Target user**: HR and recruitment manager for a small company
+
+**User profile**:
* has a need to manage a significant number of contacts
* prefer desktop apps over other types
@@ -268,65 +269,440 @@ _{Explain here how the data archiving feature will be implemented}_
* prefers typing to mouse interactions
* is reasonably comfortable using CLI apps
-**Value proposition**: manage contacts faster than a typical mouse/GUI driven app
+**Value proposition**: help the HR manager to effortlessly manage job candidates, interview notes, recruitment status and past communications in one place at a glance, simplifying recruitment with an intuitive, organized, and scalable solution.
### User stories
Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*`
-| Priority | As a … | I want to … | So that I can… |
-| -------- | ------------------------------------------ | ------------------------------ | ---------------------------------------------------------------------- |
-| `* * *` | new user | see usage instructions | refer to instructions when I forget how to use the App |
-| `* * *` | user | add a new person | |
-| `* * *` | user | delete a person | remove entries that I no longer need |
-| `* * *` | user | find a person by name | locate details of persons without having to go through the entire list |
-| `* *` | user | hide private contact details | minimize chance of someone else seeing them by accident |
-| `*` | user with many persons in the address book | sort persons by name | locate a person easily |
-
-*{More to be added}*
+| Priority | As a … | I want to … | So that I can… |
+|--------|------------|------------------------------|---------------------------------------------------------------------|
+| `* * *` | HR manager | look at the information of the interviewees | so that I can review their qualifications for the role |
+| `* * *` | HR manager | be able to add a new applicant’s information and contact details | I can keep track of potential candidates. |
+| `* * *` | HR manager | delete the information of an applicant | I know which applicants do not qualify for an interview. |
+| `* * *` | HR manager | be able to tag candidates with custom labels such as “Shortlisted” or “Rejected” | I can send out information more easily. |
+| `* * *` | HR manager | be able to tag applicants based on their stages of application (into applicants/candidates/interviewees) | I know their progress in the interviews. |
+| `* * *` | HR manager | save my candidate's information into my local storage | I can access it again in the future |
+| `* *` | HR manager | be able to sort the interviewees based on the date of their interview | it is more convenient for me to keep track of who I am interviewing |
+| `* *` | HR manager | be able to add interview notes to an interviewee profile | I can keep track of my opinions of them |
+| `* *` | HR manager | be able to search for an interviewee’s name | I can quickly find their contact details |
+| `* *` | HR manager | be able to see a list of all potential applicants | I can get an overview of how many candidates are applying |
+| `* *` | HR manager | sort candidates by their custom labels/tags | I can group them together and send them the correct information. |
+| `* *` | HR manager | receive reminders for upcoming interviews | I never miss a scheduled interview |
+| `*` | HR manager | attach resumes and cover letters to each applicant’s profile | I can quickly review their qualifications. |
+| `*` | HR manager | be able to automatically schedule interviews on applicants’ available timings | I am less likely to make mistakes during arrangement |
+| `*` | HR manager | filter the applicants based on certain characteristics | I can efficiently decide who qualifies for an interview |
+| `* *` | HR manager | be able to see the count of applicants by the respective stages of application | I can fill the job vacancies adequately. |
### Use cases
-(For all use cases below, the **System** is the `AddressBook` and the **Actor** is the `user`, unless specified otherwise)
+(For all use cases below, the **System** is the `HireHive` and the **Actor** is the `user`, unless specified otherwise)
-**Use case: Delete a person**
+**Use case: UC01: - Add a person**
**MSS**
-1. User requests to list persons
-2. AddressBook shows a list of persons
-3. User requests to delete a specific person in the list
-4. AddressBook deletes the person
+1. User chooses to add a person.
+2. User enters the details of the person.
+3. HireHive adds the person.
+4. HireHive saves the details of the added person.
+5. HireHive displays the added person.
+
+ Use case ends.
+
+**Extensions**
+* 2a. HireHive detects an invalid input in the entered details.
+ * 2a1. HireHive shows an error message.
+ * 2a2. User enters new data.
+ * Steps 2a1-2a2 are repeated until the user adds a valid input for the parameters.
+ * Use case resumes from step 3.
+
+* 2b. HireHive detects that the person already exists.
+ * 2b1. HireHive shows an error message.
+ * 2b2. User enters new data.
+ * Steps 2b1-2b2 are repeated until a person with a unique name is entered.
+ * Use case resumes from step 3.
+
+* 2c. HireHive detects an empty input for one of the parameters.
+ * 2c1. HireHive shows an error message.
+ * 2c2. User enters new data.
+ * Steps 2c1-2c2 are repeated until the user adds a valid input for all the parameters.
+ * Use case resumes from step 3.
+
+**Use case: UC02 - List all persons**
+
+**MSS**
+1. User requests to list persons.
+2. HireHive shows a list of persons.
Use case ends.
**Extensions**
+* 1a. The list is empty.
+ * 1a1. HireHive displays an empty list.
+
+ Use case ends.
+
+**Use case: UC03 - Delete a person**
+
+Preconditions: The list is not empty
+
+**MSS**
+
+1. User requests to list persons (UC02).
+2. User requests to delete a specific person in the list, using either:
+ * The person's index in the list
+ * The person's name in the list
+3. HireHive deletes the person
-* 2a. The list is empty.
+ Use case ends.
- Use case ends.
+**Extensions**
* 3a. The given index is invalid.
- * 3a1. AddressBook shows an error message.
+ * 3a1. HireHive shows an error message.
+
+ Use case resumes at step 1.
+
+* 3b. The given name does not match any person
+ * 3b1. HireHive shows an error message.
+
+ Use case resumes at step 1.
+
+* 3c. Multiple persons match the given name
+ * 3c1. HireHive shows an error message, and requests for more specific data.
+ * 3c2. User enters new data
+ * 3c3. Steps 3c1-3c2 are repeated till the data entered is correct
+
+ Use case resumes at step 3.
+
+
+**Use case: UC04 - Tag a person**
+
+**MSS**
+
+1. User requests to list persons (UC02).
+2. User specifies a person in HireHive to tag with a specific tag.
+3. HireHive tags the person with the specific tag.
+4. HireHive saves the details of the person tagged.
+5. HireHive displays the updated details of the person tagged.
+
+ Use case ends.
+
+**Extensions**
+
+* 3a. User specifies a person by a valid name, but HireHive has multiple people containing the same name.
+
+ * 3a1. HireHive shows an error message.
+ * 3a2. HireHive shows a list of persons containing the name.
+ * 3a3. HireHive shows a message to ask user to enter the full name of the person to tag.
+
+ Use case ends.
+
+* 3b. User specifies a person by a name of a person that does not exist.
+ * 3b1. HireHive shows an error message that no such person exists.
+ * 3b2. HireHive shows an empty list of persons.
+
+ Use case ends.
+
+* 3c. User specifies a person by invalid index.
+ * 3c1. HireHive shows an error message that index is invalid.
+
+ Use case ends.
+
+* 3d. User enters an invalid offset.
+ * 3d1. HireHive shows an error message that offset is invalid.
+
+ Use case ends.
+
+
+
+
+**Use case: UC05 - Edit a person**
+
+Preconditions: The list is not empty
+
+**MSS**
+
+1. User requests to edit a person.
+2. User enters the index and parameter of the person to be edited.
+3. HireHive edits the person at that index by replacing the old data at the specified parameter with what was input by the user.
+4. HireHive saves the details of the edited person.
+5. HireHive displays the person with their new details.
+
+ Use case ends.
+
+**Extensions**
+
+* 2a. HireHive detects an invalid index.
+ * 2a1. HireHive shows an error message.
+ * 2a2. User enters new data.
+ * Steps 2a1-2a2 are repeated until the user inputs a valid index.
+ * Use case resumes from step 3.
+
+* 2b. HireHive detects an invalid parameter.
+ * 2b1. HireHive shows an error message.
+ * 2b2. User enters new data.
+ * Steps 2b1-2b2 are repeated until the user inputs a valid parameter.
+ * Use case resumes from step 3.
+
+* 2c. HireHive detects an empty input.
+ * 2c1. HireHive shows an error message.
+ * 2c2. User enters new data.
+ * Steps 2c1-2c2 are repeated until the user inputs valid inputs for both index and parameter.
+ * Use case resumes from step 3.
+
+* 2d. User tries to edit the name of a person at a valid index.
+ * 2d1. HireHive detects an existing person with the same name.
+ * 2d2. HireHive shows an error message.
+ * 2d3. User enters new data
+ * Steps 2d1-2d3 are repeated until the user inputs a unique name.
+ * Use case resumes from step 2.
+
+**Use case: UC06 - Filter the list**
+
+Preconditions: The list is not empty
+
+**MSS**
+
+1. User requests to filter persons based on a certain condition (name, tag, interview date).
+2. User enters the search criteria.
+3. HireHive displays the persons who fit the criteria.
+
+ Use case ends.
+
+**Extensions**
+* 2a. HireHive detects a empty or invalid search condition.
+ * 2a1. HireHive shows an error message.
+ * 2a2. User enters new data.
+ * Steps 2a1-2a2 are repeated until the user inputs a valid condition.
+ * Use case resumes from step 3.
+
+* 2b. No entry fits the criteria.
+ * 2b1. HireHive displays an empty list.
+ * Use case ends.
+
+Use case: UC07 - Schedule an interview
+
+**MSS**
+
+1. User requests to list persons (UC02).
+2. User requests to schedule a meeting on a certain date.
+3. HireHive adds the date to the person's entry.
+4. HireHive saves the details of the person with the newly added date.
+5. HireHive displays the details of the person with the newly added date.
+
+ Use case ends.
+
+**Extensions**
+
+* 2a. User does not provide a date.
+ * 2a1. HireHive automatically schedules the interview date on the next free day.
+ * Use case resumes from step 3.
+* 3a. The given index or name is invalid.
+ * 3a1. HireHive shows an error message.
+
+Use case resumes at step 1.
+
+**Use case: UC07 - Sorting persons**
+
+Preconditions: The list is not empty
+
+**MSS**
+
+1. User requests to sort the list.
+2. HireHive sorts the list
+3. HireHive displays sorted list.
+
+ Use case ends.
+
+**Use case: UC08 - Add notes to a person**
+
+Preconditions: The list is not empty
+
+**MSS**
+
+1. User requests to add notes to a person.
+2. User enters the name of the person and the contents of the note to be added.
+3. HireHive adds the contents of the note to the person.
+4. HireHive saves the note of the person.
+5. HireHive displays the contents of the note in a popup window.
- Use case resumes at step 2.
+ Use case ends.
+
+**Extensions**
+
+* 2a. HireHive detects that name is missing.
+ * 2a1. HireHive shows an error message.
+ * 2a2. User enters new input.
+ * Steps 2a1-2a2 are repeated until the user inputs an existing name.
+ * Use case resumes from step 3.
+* 2b. HireHive detects that name is invalid.
+ * 2b2. HireHive shows an error message.
+ * 2a2. User enters new input.
+ * Steps 2b1-2b2 are repeated until the user inputs an existing name.
+ * Use case resumes from step 3.
+* 2c. The name input by the user does not match any existing name.
+ * 2c1. HireHive shows an error message.
+ * 2c2. User enters new input.
+ * Steps 2c1-2c2 are repeated until the user inputs an existing name.
+ * Use case resumes from step 3.
+* 2d. The name input by the user matches multiple names.
+ * 2d1. HireHive shows an error message.
+ * 2d2. User enters new input.
+ * Steps 2d1-2d2 are repeated until the user inputs the full name of the person.
+ * Use case resumes from step 3.
+* 2e. HireHive detects that the note is invalid.
+ * 2e1. HireHive shows an error message.
+ * 2e2. User enters new input.
+ * Steps 2e1-2e2 are repeated until the user inputs a valid note.
+ * Use case resumes from step 3.
+* 2f. The note input is empty.
+ * 2f1. HireHive accepts this as valid input and clears the note.
+ * Use case resumes from step 3.
+
+**Use case: UC09 - Display notes of a person**
+
+Preconditions: The list is not empty
+
+**MSS**
+
+1. User requests to display notes of a person.
+2. User enters the name of the person.
+3. HireHive displays the contents of the note in a popup window.
+
+**Use case: UC08 - Filtering out applicants by tag**
+
+Preconditions: The list is not empty
+
+**MSS**
+
+1. User requests to filter out the list with a tag
+2. User enters the specific tag to filter out the list
+3. HireHive displays all persons without the specified tag
+
+ Use case ends.
+
+**Extensions**
+* 2a. HireHive detects that name is missing.
+ * 2a1. HireHive shows an error message.
+ * 2a2. User enters new input.
+ * Steps 2a1-2a2 are repeated until the user inputs an existing name.
+ * Use case resumes from step 3.
+* 2b. HireHive detects that name is invalid.
+ * 2b2. HireHive shows an error message.
+ * 2a2. User enters new input.
+ * Steps 2b1-2b2 are repeated until the user inputs an existing name.
+ * Use case resumes from step 3.
+* 2c. The name input by the user does not match any existing name.
+ * 2c1. HireHive shows an error message.
+ * 2c2. User enters new input.
+ * Steps 2c1-2c2 are repeated until the user inputs an existing name.
+ * Use case resumes from step 3.
+* 2d. The name input by the user matches multiple names.
+ * 2d1. HireHive shows an error message.
+ * 2d2. User enters new input.
+ * Steps 2d1-2d2 are repeated until the user inputs the full name of the person.
+ * Use case resumes from step 3.
+
+**Use case UC10 - Clear AddressBook**
+
+**MSS**
+
+1. User requests to clear the AddressBook.
+2. User enters `clear` in the command box.
+3. HireHive clears all existing data, and AddressBook is now empty.
+
+ Use case ends.
+
+**Use case UC11 - Getting Help**
+
+Preconditions: User device has a working Internet connection.
+
+**MSS**
+
+1. User requests help in using HireHive.
+2. User enters `help` in the command box.
+3. HireHive opens the help window with a URL to the User Guide.
+4. User copies the URL with the `Copy URL` button on the right side of the help window.
+5. User accesses the User Guide through a browser after pasting the URL in.
+
+ Use case ends.
+
+**Extensions**
+
+* 2a. User clicks on the `Help` button on the top left of the display window.
+ * 2a1. A dropdown display shows another `Help` button.
+ * 2a2. User clicks on the `Help` button.
+ * Use case resumes from step 3.
+* 2b. User uses the shortcut to access the `Help` window. On both Mac and Windows, press `fn` + `F1`.
+ * Use case resumes from step 3.
+
+**Use case: UC12 - Filtering out applicants by tag**
+
+Preconditions: The list is not empty
+
+**MSS**
+
+1. User requests to filter out the list with a tag
+2. User enters the specific tag to filter out the list
+3. HireHive displays all persons without the specified tag
+
+**Extensions**
+* 2a. HireHive detects an empty tag
+ * 2a1. HireHive shows an error message
+ * 2a2. User enters new data
+ * Steps 2a1-2a2 are repeated till user inputs a tag
+
+ Use case resumes at step 3.
+
+* 2b. HireHive detects an unknown tag
+ * 2b1. HireHive shows an error message
+ * 2b2. User enters new data
+ * Steps 2b1-2b2 are repeated till users input a valid tag
+
+ Use case resumes at step 3.
+
+**Use case UC13 - Exiting HireHive**
+
+**MSS**
+
+1. User requests to exit HireHive.
+2. User enters `exit` as input.
+3. HireHive saves the data in its current state and closes.
+
+ Use case ends.
+
+**Extensions**
+
+* 2a. User clicks on the `File` button on the top left of the display window.
+ * 2a1. A dropdown display shows the `Exit` button.
+ * 2a2. User clicks on the `Exit` button.
+ * Use case resumes from step 3.
+* 2b. User clicks on the close button of the display window. On Mac, it is in the top left corner. On Windows, it is in the top right corner.
+ * Use case resumes from step 3.
-*{More to be added}*
### Non-Functional Requirements
1. Should work on any _mainstream OS_ as long as it has Java `17` or above installed.
2. Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage.
3. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
-
-*{More to be added}*
+4. Operations by the system should return responses in under 2 seconds.
+5. Data should be backed up or stored in alternative formats, in the event that the default format which the data is loaded from becomes corrupted.
+6. Data must be saved immediately upon change to ensure data persistence.
### Glossary
* **Mainstream OS**: Windows, Linux, Unix, MacOS
* **Private contact detail**: A contact detail that is not meant to be shared with others
+* **Applicants**: Anyone who submits an application to the company
+* **Candidates**: Applicants who are potentially qualified for the job
+* **Interviewees**: Candidates that accept an interview offer
+* **Offered**: Interviewees that receive job offers
+* **Rejected**: Interviewees that did not receive job offers
--------------------------------------------------------------------------------------------------------------------
@@ -354,29 +730,322 @@ testers are expected to do more *exploratory* testing.
1. Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
-1. _{ more test cases … }_
+### Viewing help
+
+1. Viewing help page
+
+ 1. Prerequisites: Application must be running.
+
+ 2. Test case: `help`
+ Expected: A 'Help' window pops up, with the link to the user guide, that can be copied.
+
+ 3. Test case: `help 1`
+ Expected: A 'Help' window pops up, with the link to the user guide, that can be copied.
+
+### Adding a person
+
+1. Adding a person
+
+ 1. Prerequisites: Application must be running.
+
+ 2. Test case: `add n/Betsy Crowe e/betsycrowe@example.com a/Ang Mo Kio Street 22 p/87654321 r/senior consulting analyst`
+ Expected: A person with name "Betsy Crowe", email "betsycrowe@example.com", address "Ang Mo Kio Street 22", phone number "87654321", applying for the "senior consulting analyst" role is added to the bottom of the existing list. Added person is given an index that follows immediately after the last assigned index.
+
+ 3. Test case: `add n/John Doe a/Bishan Street 20 p/98765432 r/senior consulting intern`
+ Expected: No person is added. Error details shown in the status message.
+
+ 4. Test case: `add n/John Doe e/john@gmail.com a/Bishan Street 20 p/98765432 r/senior consulting intern t/applicant`
+ Expected: No person is added. Error details shown in the status message.
+
+ 5. Test case: `add n/John Doe e/john@gmail.com a/Bishan Street 20 p/98765432 r/senior consulting intern i/Likes to talk`
+ Expected: No person is added. Error details shown in the status message.
+
+ 6. Test case: `add n/小丽 e/john@gmail.com a/Bishan Street 20 p/98765432 r/senior consulting intern`
+ Expected: No person is added. Error details shown in the status message.
+
+### Listing persons
+
+1. Listing all the persons in HireHive
+
+ 1. Prerequisites: List is not empty
+
+ 2. Test case: `list`
+ Expected: All the persons in the list are listed. Topmost person in the list is the oldest person who was added to the list, while the bottom-most person was the person who was most recently added to the list. Index of persons should start from 1 and increase from top to bottom of the list.
+ 3. Test case: `list help`
+ Expected: All the persons in the list are listed. Topmost person in the list is the oldest person who was added to the list, while the bottom-most person was the person who was most recently added to the list. Index of persons should start from 1 and increase from top to bottom of the list.
+
+### Sorting persons
+
+1. Sorting all the persons shown in the list.
+
+ 1. Prerequisites: Multiple persons in the list, with some persons having interview dates
+
+ 2. Test case: `sort`
+ Expected: All the persons in the list are sorted. Those with interview dates are sorted in chronological order, while those without interview dates are pushed to the back of the list, in the original order they were in previously. New index given based on the newly sorted order of the list.
+
+ 3. Test case: `list help`
+ Expected: All the persons in the list are sorted. Those with interview dates are sorted in chronological order, while those without interview dates are pushed to the back of the list, in the original order they were in previously. New index given based on the newly sorted order of the list.
### Deleting a person
-1. Deleting a person while all persons are being shown
+1. Deleting a person by index
1. Prerequisites: List all persons using the `list` command. Multiple persons in the list.
+
+ 2. Test case: `delete 1`
+ Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message.
- 1. Test case: `delete 1`
- Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated.
-
- 1. Test case: `delete 0`
+ 3. Test case: `delete 0`
Expected: No person is deleted. Error details shown in the status message. Status bar remains the same.
- 1. Other incorrect delete commands to try: `delete`, `delete x`, `...` (where x is larger than the list size)
+ 4. Other incorrect delete commands to try: `delete`, `delete x`, `...` (where x is larger than the list size)
Expected: Similar to previous.
-1. _{ more test cases … }_
+1. Deleting a person by name
+ 1. Prerequisites: List all persons using `list` command. Multiple persons in the list
+
+ 2. Test case: `delete n/Alice`
+ Expected: Contact with the name "Alice" is deleted from the list. Details of the deleted contact shown in status message.
+ 3. Test case: `delete n/john doe`
+ Expected: Contact with the name "John Doe" is deleted from the list. Details of the deleted contact shown in status message.
+ 4. Test case: `delete n/nonexistent name`
+ Expected: Error message is shown, stating that no such contact exists in the list
+ 5. Test case: `delete john`
+ Expected: Error message for invalid command format is displayed in status message with example.
+
+### Tagging a person
+
+1. Tagging a person by name, with tag
+ 1. Prerequisites: Use the same persons list as when you first ran HireHive.jar
+ 2. Test case: `tag n/alice t/candidate`
+ Expected: Contact with name "Alice Yeoh" is tagged as "Candidate". Details of the tagged contact shown in the
+ status message.
+ 3. Test case: `tag n/alice t/CANDIDATE`
+ Expected: Contact with name "Alice Yeoh" is tagged as "Candidate". Details of the tagged contact shown in the
+ status message.
+ 4. Test case: `tag n/alice t/cAnDiDaTe`
+ Expected: Contact with name "Alice Yeoh" is tagged as "Candidate". Details of the tagged contact shown in the
+ status message.
+ 5. Test case: `tag n/ALICE t/candidate`
+ Expected: Contact with name "Alice Yeoh" is tagged as "Candidate". Details of the tagged contact shown in the
+ status message.
+ 6. Test case: `tag n/aLiCe t/CANDIDATE`
+ Expected: Contact with name "Alice Yeoh" is tagged as "Candidate". Details of the tagged contact shown in the
+ status message.
+ 7. Test case: `tag n/alice t/test`
+ Expected: Error message for invalid command format shown in status message with command format and example.
+2. Tagging a person by index, with tag
+ 1. Prerequisites: Use the same persons list as when you first ran HireHive.jar
+ 2. Test case: `tag 1 t/interviewee`
+ Expected: First contact is tagged as "Interviewee". Details of the tagged contact shown in the
+ status message.
+ 3. Test case: `tag 1 t/INTERVIEWEE`
+ Expected: First contact is tagged as "Interviewee". Details of the tagged contact shown in the
+ status message.
+ 4. Test case: `tag 1 t/iNtErViEwEe`
+ Expected: First contact is tagged as "Interviewee". Details of the tagged contact shown in the
+ status message.
+ 5. Test case: `tag 1 t/test`
+ Expected: Error message for invalid command format shown in status message with command format and example.
+3. Tagging a person by name, with offset
+ 1. Prerequisites: Use the same persons list as when you first ran HireHive.jar
+ 2. Test case: `tag +1 n/bernice`
+ Expected: Contact with name "Bernice Yu" is tagged as "Offered". Details of the tagged contact shown
+ in the status message (if tag was "Interviewee").
+ 3. Test case `tag -2 n/charlotte`
+ Expected: Contact with name "Charlotte Oliveiro" is tagged as "Rejected". Details of the tagged contact shown
+ in the status message (if tag was "Candidate").
+
+### Scheduling interview date
+
+1. Scheduling an interview date for a person by name
+ 1. Prerequisites: Use the same persons list as when you first ran HireHive.jar
+ 2. Test case: `schedule n/alice d/04/05/2025`
+ Expected: Contact with name "Alice Yeoh" has interview date scheduled as "04/05/2025". Details of the scheduled
+ contact shown in the status message.
+ 3. Test case: `schedule n/alice d/test`
+ Expected: Error message for invalid command format shown in status message with command format and example.
+ 4. Test case: `schedule n/alice 04/05/2025`
+ Expected: Error message for no persons found as there is no person with the name "alice 04/05/2025"
+2. Scheduling an interview date for a person by index
+ 1. Prerequisites: Use the same persons list as when you first ran HireHive.jar
+ 2. Test case: `schedule 1 d/04/05/2025`
+ Expected: First contact has interview date scheduled as "04/05/2025". Details of the scheduled contact shown in the status message.
+ 3. Test case: `schedule 1 d/test`
+ Expected: Error message for invalid command format shown in status message with command format and example.
+ 4. Test case: `schedule 1 01/02/2025`
+ Expected: Error message for invalid integer as "1 01/02/2025" is not a non-zero unsigned integer.
+3. Automatically scheduling the next interview date
+ 1. Prerequisites: Use the same persons list as when you first ran HireHive.jar
+ 2. Test case: `schedule 1`
+ Expected: First contact will be updated to tomorrow's date.
+ 3. Test case: `schedule n/alice`
+ Expected: Alice's contact will be updated to tomorrow's date
+
+### Show persons with upcoming interviews
+
+1. Show persons with upcoming interviews
+ 1. Prerequisites: Use the same persons list as when you first ran HireHive.jar. `list` command is run before the execution of the below commands.
+ 2. Test case: `remind 100`
+ Expected: Only the contact with name "David Li" and interview date "06/07/2025" is shown in the list. Success
+ message shown in the status message.
+ 3. Test case: `remind -1`
+ Expected: Error message for invalid command format shown in status message with command format and example.
+ 4. Test case: `remind 1000000000000000000000000000000`
+ Expected: Error message for invalid integer is shown.
+
+### Filtering for applicants with tag
+
+1. Filtering for applicants with specified tag
+ 1. Prerequisites: Use the same persons list as when you first ran HireHive.jar. `list` command is run before the execution of the below commands.
+ 2. Test case: `filter t/interviewee`
+ Expected: All contacts with the interviewee tag will be displayed on the list.
+ 3. Test case: `filter t/iNtErViEweE`
+ Expected: All contacts with the interviewee tag will be displayed on the list.
+ 4. Test case: `filter t/abc`
+ Expected: Error message showing the valid tags will be displayed.
+ 5. Test case `filter candidate`
+ Expected: Error message for invalid command format shown in status message with command format and example.
+
+### Filtering out applicants with tag
+
+1. Filtering out all applicants with specified tag, and the remaining list contains applicants without that tag
+ 1. Prerequisites: Use the same persons list as when you first ran HireHive.jar. `list` command is run before the execution of the below commands.
+ 2. Test case: `filterout t/interviewee`
+ Expected: All contacts without the interviewee tag will be displayed on the list
+ 3. Test case: `filterout t/Applicant`
+ Expected: All contacts without the applicant tag will be displayed on the list
+ 4. Test case: `filterout t/testing`
+ Expected: Error message showing the valid tags will be displayed.
+ 5. Test case `filterout candidate`
+ Expected: Error message for invalid command format shown in status message with command format and example.
+
+### Adding note of a person
+
+1. Adding note of a person
+ 1. Prerequisite: Use the initial persons list loaded when first running HireHive.jar
+ 2. Test case: `newnote n/Bernice Yu i/20 years old` Expected output: "Added and displaying note of: Bernice Yu; Phone: 99272758; Email: berniceyu@example.com; Address: Blk 30 Lorong 3 Serangoon Gardens, #07-18; Role: HR manager; Date: 01/03/2025; Tag: INTERVIEWEE Success: Applicant data has been saved." Additionally, popup window shows "20 years old" in white font.
+ 3. Test case: `newnote n/BeRnIcE i/19 years old` Expected output: same as test case 1, but popup window shows "19 years old" in white font.
+ 4. Test case: `newnote n/ Bernice i/18 years old` Expected output: same as test case 1, but popup window shows "18 years old" in white font.
+ 5. Test case: `newnote n/Yu i/` Expected output: same as test case 1, but popup window shows "Currently empty..." in yellow font.
+ 6. Test case: `newnote n/bErNiCe yU i/Currently empty...` Expected output: same as test case 1, but popup window shows "Currently empty..." in white font.
+
+### Displaying note of a person
+
+1. Displaying note of a person
+ 1. Prerequisite: Use the initial persons list loaded when first running HireHive.jar
+ 2. Test case: `displaynote n/Alice Yeoh` Expected output: "Displaying note of: Alice Yeoh; Phone: 87438807; Email: alexyeoh@example.com; Address: Blk 30 Geylang Street 29, #06-40; Role: UI designer; Date: ; Tag: APPLICANT" Additionally, popup window shows "20 years old" in white font.
+ 3. Test case: `displaynote n/BeRnIcE yU` Expected output: "Displaying note of: Bernice Yu; Phone: 99272758; Email: berniceyu@example.com; Address: Blk 30 Lorong 3 Serangoon Gardens, #07-18; Role: HR manager; Date: 01/03/2025; Tag: INTERVIEWEE" Additionally, popup window shows "Currently empty..." in yellow font.
+ 4. Test case: `displaynote n/Irfan` Expected output: "Displaying note of: Irfan Ibrahim; Phone: 92492021; Email: irfan@example.com; Address: Blk 47 Tampines Street 20, #17-35; Role: Software Engineer; Date: 06/03/2025; Tag: REJECTED" Additionally, popup window shows "30 years old" in white font.
+ 5. Test case: `newnote n/raHIM i/` Expected output: same as test case 3.
+
+### Editing the details of a person
+
+1. Editing the details of a person
+ 1. Prerequisites: Run `list` command and ensure there are at least 2 people in the list
+ 2. Test case: `edit 2 p/88888888`
+ Expected: The phone number of the 2nd person in the list is changed to 88888888
+ 3. Test case: `edit 2 p/88888888 e/g@gmail.com`
+ Expected: The phone number and email of the 2nd person in the list is changed to 88888888 and g@gmail.com respectively.
+ 4. Test case: `edit 1 i/`
+ Expected: The note of the 1st person in the list is cleared.
+ 5. Test case: `edit 0 p/88888888`
+ Expected: Nobody's details are edited. Error is displayed.
+
+### Finding a person
+
+1. Finding a person with some keywords
+ 1. Prerequisites: Use the same persons list as when you first ran HireHive.jar. `list` command is run before the execution of the below commands.
+ 2. Test case: `find Alice`
+ Expected: Displays the applicant(s) whose name contains the keyword 'Alice'
+
+### Clearing all entries
+
+1. Clearing all entries in HireHive
+
+ 1. Prerequisites: List contains people.
+
+ 2. Test case: `clear`
+ Expected: All the persons in the list are cleared. List is now empty.
+
+ 3. Test case: `Clear`
+ Expected: Nothing is cleared. Error details shown in the status message.
+
+### Exiting the program
+
+1. Exiting the program
+
+ 1. Prerequisites: Program was originally running.
+
+ 2. Test case: `exit`
+ Expected: Program exits and closes.
+
+### Loading data
+
+1. Sample data is loaded
+ 1. Test case: On first launch of `HireHive.jar`, this should automatically load the sample data. Expected output: "Success: Sample applicant data has been loaded successfully."
+ 2. Test case: Delete `addressbook.json` under folder `data` if it exists, then launch `HireHive.jar`. Expected output: same as test case i.
+
+2. Saved data is loaded
+ 1. Test case: perform a command that modifies data except `clear` e.g. `delete 1`, then `exit` the application. Relaunch `HireHive.jar`. Expected output: "Success: Applicant data has been loaded successfully."
+
+3. Saved data is empty
+ 1. Test case: perform `clear` command e.g. `clear`, then `exit` the application. Relaunch `HireHive.jar`. Expected output: "Current address book is empty. This might be due to corrupted data. WARNING: Please check if data/addressbook.json has old corrupted data and attempt to fix it, otherwise any new successful commands will overwrite those contents."
+
+4. No data is loaded due to corruption of data
+ 1. Prerequisite: Launch `HireHive.jar` at least once and exit.
+ 2. Test case: Delete `addressbook.json` under folder `data` if it exists, then copy `config.json` into the same folder. Rename `config.json` to `addressbook.json`. Expected output: "Current address book is empty. This might be due to corrupted data. WARNING: Please check if data/addressbook.json has old corrupted data and attempt to fix it, otherwise any new successful commands will overwrite those contents."
+
+## **Appendix: Planned Enhancements**
+**Team size - 5**
+
+### 1. Support multiple applicants with the same name
+
+**Current Feature Flaw:**
+
+HireHive currently does not allow duplicate names, which does not reflect real-world scenarios where different applicants may have identical names.
+
+**Proposed implementation:**
+ 1. Modify the `add` command to support adding multiple applicants with the same name.
+ * Compare applicants' phone numbers and emails instead of names to determine if they are the same applicant.
+ * In the real world, while 2 applicants may have the same name, no 2 applicants should have the same phone number or email. Thus, phone numbers and emails are a better way to reflect real-world scenarios and check for duplicates.
+ 2. Update `displaynote` and `newnote` command to also accept `INDEX`, instead of just a person's `NAME`.
+ * i.e. allow `displaynote INDEX` and `newnote INDEX i/NOTE`, on top of the current functionality, `displaynote n/NAME` and `newnote n/NAME i/NOTE`
+ * If applicants have the same name, they can be identified by their index instead, which is unique for each applicant.
+ * Index format: Each applicant is identified by their unique index
+ * Name format:
+ * Single match: Commands executes as per normal
+ * Multiple match (i.e. Multiple applicants with the same name)
+ * A list of applicants with the same name is displayed.
+ * Users can identify the desired applicant by using the command with the unique index of the person.
+
+### 2. Support phone numbers from different countries
+
+**Current Feature Flaw:**
+
+HireHive currently does not support international phone numbers. However, we understand that this may not be applicable in the real world as applicants may be on work permits that come to Singapore to work.
+
+**Proposed implementation:**
+ 1. Modify the `add` command to make it more flexible and allow international formats.
+ * Accept phone numbers with country codes.
+ * Allow for telephone numbers that start with numbers other than 9/8/6 and allow for longer telephone numbers.
+
+### 3. Prevent the app from refreshing when user types another command after sorting/filtering the list
+
+**Current Feature Flaw:**
+
+After a user sorts or filters the list, if the user enters another command like `delete`, HireHive currently resets the displayed list to its original state and the user loses the sorted or filtered list. This may be inconvenient for users as it would require them to filter or sort the list again.
+
+**Proposed implementation:**
+ 1. Modify `filter` and `sort` such that the displayed list is always retained unless the command `list` is entered.
+
+### 4. Make loading AddressBook message more specific
-### Saving data
+**Current Feature Flaw:**
-1. Dealing with missing/corrupted data files
+The current message for loading an empty AddressBook and loading an invalid AddressBook is the same. A warning is given to users who simply have an empty AddressBook, even though this behaviour is completely valid.
- 1. _{explain how to simulate a missing/corrupted file, and the expected behavior}_
+**Proposed implementation:**
+1. When an AddressBook with invalid data is loaded, show the error message "WARNING: Data in data/addressbook.json is corrupted. Please resolve it manually, otherwise any new successful commands will overwrite those contents."
+2. When an empty AddressBook is loaded, show the message: "Success: No applicant data currently."
-1. _{ more test cases … }_
diff --git a/docs/SettingUp.md b/docs/SettingUp.md
index aef33ec72fd..d675296d601 100644
--- a/docs/SettingUp.md
+++ b/docs/SettingUp.md
@@ -23,7 +23,7 @@ If you plan to use Intellij IDEA (highly recommended):
1. **Import the project as a Gradle project**: Follow the guide [_[se-edu/guides] IDEA: Importing a Gradle project_](https://se-education.org/guides/tutorials/intellijImportGradleProject.html) to import the project into IDEA.
:exclamation: Note: Importing a Gradle project is slightly different from importing a normal Java project.
1. **Verify the setup**:
- 1. Run the `seedu.address.Main` and try a few commands.
+ 1. Run the `hirehive.address.Main` and try a few commands.
1. [Run the tests](Testing.md) to ensure they all pass.
--------------------------------------------------------------------------------------------------------------------
diff --git a/docs/Testing.md b/docs/Testing.md
index 8a99e82438a..f248056c811 100644
--- a/docs/Testing.md
+++ b/docs/Testing.md
@@ -31,6 +31,6 @@ This project has three types of tests:
1. *Unit tests* targeting the lowest level methods/classes.
e.g. `seedu.address.commons.StringUtilTest`
1. *Integration tests* that are checking the integration of multiple code units (those code units are assumed to be working).
- e.g. `seedu.address.storage.StorageManagerTest`
+ e.g. `storage.hirehive.address.StorageManagerTest`
1. Hybrids of unit and integration tests. These test are checking multiple code units as well as how the are connected together.
- e.g. `seedu.address.logic.LogicManagerTest`
+ e.g. `logic.hirehive.address.LogicManagerTest`
diff --git a/docs/UserGuide.md b/docs/UserGuide.md
index 27c2d1cf16c..678fa7b7d5f 100644
--- a/docs/UserGuide.md
+++ b/docs/UserGuide.md
@@ -1,42 +1,120 @@
---
layout: page
title: User Guide
----
-AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized for use via a Command Line Interface** (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, AB3 can get your contact management tasks done faster than traditional GUI apps.
+---
-* Table of Contents
-{:toc}
+# Welcome to HireHive!
+
+Tired of drowning in resumes and losing track of candidates? Meet HireHive— your **personal, all-in-one** hiring assistant designed to simplify the hiring process so you can focus on what matters most - finding the best talent.
+
+We combine the speed of keyboard commands with an intuitive visual interface to help you:
+- Find top talent faster with **lightning-fast** keyboard shortcuts
+- Stay effortlessly organized with all **[applicant](#glossary) details in one place**
+- Make better hiring decisions with **structured interview notes**
+
+Ready to revolutionise your hiring? Let's begin!
+
+- [Quick start](#quick-start)
+- [Command Summary](#command-summary)
+- [Features](#features)
+ - [View help: `help`](#view-help-help)
+ - [Adding and modifying applicants](#adding-and-modifying-applicants)
+ - [Add an applicant: `add`](#add-an-applicant-add)
+ - [Edit an applicant: `edit`](#edit-an-applicant-edit)
+ - [Tag an applicant: `tag`](#tag-an-applicant-tag)
+ - [Add note to applicant: `newnote`](#add-note-to-applicant-newnote)
+ - [Schedule interview dates: `schedule`](#schedule-interview-dates-for-applicants--schedule)
+ - [Listing applicant information](#listing-applicant-information)
+ - [Display note of applicant: `displaynote`](#display-note-of-applicant-displaynote)
+ - [Sort applicants `sort`](#sort-applicants-sort)
+ - [List all applicants: `list`](#list-all-applicants-list)
+ - [Filtering applicant information](#filtering-applicant-information)
+ - [Filter applicants by tag: `filter`](#filter-applicants-by-tag-filter)
+ - [Filtering out applicants with tag: `filterout`](#filtering-out-applicants-with-tag-filterout)
+ - [Remind you of upcoming interviews: `remind`](#show-applicants-with-upcoming-interviews-remind)
+ - [Find applicants by name `find`](#find-applicants-by-name-find)
+ - [Deletion of applicants](#deletion-of-applicants)
+ - [Delete an applicant: `delete`](#delete-an-applicant-delete)
+ - [Clear all entries: `clear`](#clear-all-entries--clear)
+ - [Exit the program: `exit`](#exit-the-program--exit)
+ - [Save the data](#save-the-data)
+ - [Edit the data file](#edit-the-data-file)
+- [FAQ](#faq)
+- [Known Issues](#known-issues)
+- [Glossary](#glossary)
--------------------------------------------------------------------------------------------------------------------
-## Quick start
-1. Ensure you have Java `17` or above installed in your Computer.
- **Mac users:** Ensure you have the precise JDK version prescribed [here](https://se-education.org/guides/tutorials/javaInstallationMac.html).
+## Quick start
+1. To use Hirehive, you need Java `17` or above installed in your computer.
+ - For **Mac users:** Ensure you have the precise version prescribed [here](https://se-education.org/guides/tutorials/javaInstallationMac.html).
-1. Download the latest `.jar` file from [here](https://github.com/se-edu/addressbook-level3/releases).
+2. Download the latest HireHive `.jar` file from [here](https://github.com/AY2425S2-CS2103T-F13-3/tp/releases).
-1. Copy the file to the folder you want to use as the _home folder_ for your AddressBook.
+3. Copy the downloaded file to a folder where you would like to store HireHive (e.g. "Documents" or "Desktop" or a new folder "HireHive") .
-1. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar addressbook.jar` command to run the application.
- A GUI similar to the below should appear in a few seconds. Note how the app contains some sample data.
- 
+4. Run HireHive.
+ - Find the folder that you stored HireHive previously (e.g. "Documents" or "Desktop" or "HireHive").
+ - Right-click on the folder and choose:
+ - For **Mac users**: "New terminal at Folder".
+ - For **Windows users**: "Open in terminal".
+ - Type `java -jar hirehive.jar` command in the opened terminal and press Enter to run the HireHive application.
+ - A [GUI](#glossary) similar to the below should appear in a few seconds. Note how the app contains some sample data.
+ 
-1. Type the command in the command box and press Enter to execute it. e.g. typing **`help`** and pressing Enter will open the help window.
+5. To use HireHive, you can type a command in the command box and press Enter to execute it. e.g. typing `help` and pressing Enter will open the help window.
Some example commands you can try:
- * `list` : Lists all contacts.
+ * `list` : Lists all applicants.
+
+ * `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01 r/intern`: Adds an applicant named `John Doe` to HireHive, with his relevant information
- * `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` : Adds a contact named `John Doe` to the Address Book.
+ * `edit 3 n/Josef` : Edits the name of the 3rd applicant in the list to Josef
- * `delete 3` : Deletes the 3rd contact shown in the current list.
+ * `find John Doe`: Searches for John Doe in the current list.
- * `clear` : Deletes all contacts.
+ * `tag n/John Doe t/interviewee` : Tags John Doe with the 'interviewee' tag
+
+ * `delete n/John Doe` : Deletes the applicant `John Doe` from the current list.
* `exit` : Exits the app.
-1. Refer to the [Features](#features) below for details of each command.
+
+
+ **:information_source: Note:**
+ Note that in HireHive, every applicant should **contain a [unique](#glossary) name**!
+
+
+6. You can refer to the [Features](#features) section below for details of each command.
+
+[Back to top](#welcome-to-hirehive)
+
+--------------------------------------------------------------------------------------------------------------------
+
+## Command summary
+
+| Action | Format, Examples |
+|-------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| **[Help](#view-help-help)** | `help` |
+| **[Add](#add-an-applicant-add)** | `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS r/ROLE` e.g. `add n/James Ho p/87654321 e/jamesho@example.com a/123, Clementi Rd, 1234665 r/software engineer intern` |
+| **[Edit](#edit-an-applicant-edit)** | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG] [i/NOTE] [id/DATE]` e.g. `edit 2 n/James Lee e/jameslee@example.com` |
+| **[Tag](#tag-an-applicant-tag)** | `tag n/NAME t/TAG` e.g. `tag n/John Doe t/Applicant` `tag INDEX t/TAG` e.g. `tag 1 t/Candidate` `tag OFFSET n/NAME` e.g. `tag +1 n/John Doe` |
+| **[NewNote](#add-notes-to-applicant-newnote)** | `newnote n/NAME i/NOTE` e.g. `newnote n/John Doe i/25 years old` |
+| **[Schedule](#schedule-interview-dates-for-applicants--schedule)** | 1. `schedule n/NAME [id/DATE]` e.g. `schedule n/John Doe id/17/04/2025` 2. `schedule INDEX [id/DATE]` e.g. `schedule 2 d/17/04/2025` |
+| **[DisplayNote](#display-note-of-applicant-displaynote)** | `displaynote n/NAME` e.g. `displaynote n/John Doe` |
+| **[Sort](#sort-applicants-sort)** | `sort` |
+| **[List](#list-all-applicants-list)** | `list` |
+| **[Filter](#filter-applicants-by-tag-filter)** | `filter t/TAG` e.g. `filter t/Applicant` |
+| **[FilterOut](#filtering-out-applicants-with-tag-filterout)** | `filterout t/TAG` e.g. `filterout t/Applicant` |
+| **[Reminder](#show-applicants-with-upcoming-interviews-remind)** | `remind DAYS` e.g. `remind 3` |
+| **[Find](#find-applicants-by-name-find)** | `find KEYWORD [MORE_KEYWORDS]` e.g. `find James Jake` |
+| **[Delete](#delete-an-applicant-delete)** | 1. `delete n/NAME` e.g. `delete n/John Doe` 2. `delete INDEX` e.g. `delete 2` |
+| **[Clear](#clear-all-entries--clear)** | `clear` |
+| **[Exit](#exit-the-program--exit)** | `exit` |
+
+[Back to top](#welcome-to-hirehive)
--------------------------------------------------------------------------------------------------------------------
@@ -46,155 +124,475 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo
**:information_source: Notes about the command format:**
-* Words in `UPPER_CASE` are the parameters to be supplied by the user.
+* Words in `UPPER_CASE` are the parameters to be supplied by you.
e.g. in `add n/NAME`, `NAME` is a parameter which can be used as `add n/John Doe`.
* Items in square brackets are optional.
- e.g `n/NAME [t/TAG]` can be used as `n/John Doe t/friend` or as `n/John Doe`.
+ e.g `n/NAME [i/NOTE]` can be used as `n/John Doe i/27 years old` or as `n/John Doe`.
* Items with `…` after them can be used multiple times including zero times.
- e.g. `[t/TAG]…` can be used as ` ` (i.e. 0 times), `t/friend`, `t/friend t/family` etc.
+ e.g. `[t/TAG]…` can be used as ` ` (i.e. 0 times), `t/interviewee`, `t/shortlisted` etc.
* Parameters can be in any order.
e.g. if the command specifies `n/NAME p/PHONE_NUMBER`, `p/PHONE_NUMBER n/NAME` is also acceptable.
-* Extraneous parameters for commands that do not take in parameters (such as `help`, `list`, `exit` and `clear`) will be ignored.
+* Extraneous parameters for commands that do not take in parameters (such as `help`, `list`, `exit`, `sort` and `clear`)
+ will be ignored.
e.g. if the command specifies `help 123`, it will be interpreted as `help`.
-
-* If you are using a PDF version of this document, be careful when copying and pasting commands that span multiple lines as space characters surrounding line-breaks may be omitted when copied over to the application.
-### Viewing help : `help`
+[Back to top](#welcome-to-hirehive)
-Shows a message explaning how to access the help page.
+### View help: `help`
+
+Shows a message explaining how you can access the help page that can assist you in understanding the different features of HireHive and how they work.

Format: `help`
+[Back to top](#welcome-to-hirehive)
+
+### Adding and modifying applicants
+
+### Add an applicant: `add`
+
+You can add a new applicant to HireHive when someone new applies to your company!
+
+Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS r/ROLE`
+
+* NAME:
+ - Names should only contain **English letters**, **spaces**, and the following symbols: **, ( ) / . @ - '**
+ - Example: `Ali s/o Mohammed`, `Rachel-Natalie`, `Si Min, Rachel O' Connor` are allowed names.
+ - Names **should not be blank or start with a symbol**.
+ - Example: `@Natalie` is not allowed
+ - Please **do not use numbers** in names.
+ - Example: `R4chel` is not allowed
+ - Names are **[case-insensitive](#glossary)**, and is displayed as how you type it.
+
+* PHONE_NUMBER:
+ - Please input a phone number that **start with 9/8/6** and is **exactly 8 digits** long.
+ - Please **do not use spaces**
+
+* EMAIL:
+ - Emails should be of the format **local-part@domain** and adhere to the following constraints:
+ 1. local-part:
+ - The local-part should only contain **[alphanumeric](#glossary) characters** and the special characters: **+_.-**
+ - The local-part **should not start or end with any special characters**.
+ 2. domain:
+ - The domain name is made up of domain labels that may or may not be separated by periods.
+ - The domain name must:
+ - end with a domain label **at least 2 characters** long, and
+ - have each domain label **start and end with [alphanumeric](#glossary) characters**, and
+ - have each domain label consist of [alphanumeric](#glossary) characters, separated only by hyphens, if any.
+
+* ADDRESS:
+ - Addresses can take any values, and it should not be blank
+
+* ROLE:
+ - Roles should only **contain [alphanumeric](#glossary) characters and spaces**, and it should not be blank.
+
+
+
+
+**:information_source: Note:**
+Every applicant in HireHive should **contain a [unique](#glossary) name**!
+ - i.e. HireHive ensures that there are no applicants in HireHive that have the same name!
+ - More specifically, applicants can share the same phone number, email, address and role, but **not name**!
+ - Example: `add n/John Doe p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 r/Software Engineer` and
+ `add n/John Wee p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 r/Software Engineer` are treated as 2 different applicants and both applicants can be added!
+
+
+
:bulb: **Tip:**
+There is no need to manually add a tag as the `Applicant` tag is automatically assigned when you add a new applicant to HireHive.
+
+
+Examples:
+* `add n/Betsy Crowe e/betsycrowe@example.com a/Ang Mo Kio Street 22 p/87654321 r/senior consulting analyst`:
+Adds an applicant with the name `Betsy Crowe`, who has `betsycrowe@example.com` as their email, `Ang Mo Kio Street 22`
+as their address, `87654321` as their phone number, and is applying for the `senior consulting analyst` role
+
+
+
+[Back to top](#welcome-to-hirehive)
+
+### Edit an applicant: `edit`
+
+If you have accidentally mistyped some details, you can edit the information of an existing applicant in HireHive!
+
+Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG] [r/ROLE] [i/NOTE] [id/DATE]`
+
+* Edits the applicant at the specified `INDEX`. The index refers to the index number shown in the displayed applicant list. The index **must be a positive integer** 1, 2, 3, …
+* At least one of the optional fields must be provided.
+* The provided values will replace the existing information in the respective fields.
+
+
+
+**:information_source: Note:**
+* All the fields provided should follow the same rules as the [Add command](#add-an-applicant-add)
+* Every applicant should have a **[unique](#glossary)** name
+
+
+
+Examples:
+* `edit 1 p/91234567 e/johndoe@example.com` Edits the phone number and email address of the 1st applicant to be `91234567` and `johndoe@example.com` respectively.
+
+
+
+[Back to top](#welcome-to-hirehive)
+
+
+### Tag an applicant: `tag`
-### Adding a person: `add`
+You can change the tag to a specific applicant from HireHive to easily differentiate between all your applicants!
-Adds a person to the address book.
+Format:
-Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…`
+Command | Description
+--------|------------------
+`tag n/NAME t/TAG` | Tags by name.
+`tag INDEX t/TAG` | Tags by index.
+`tag OFFSET n/NAME` | Offset tag of named applicant.
:bulb: **Tip:**
-A person can have any number of tags (including 0)
+In the event where you are unable to select a candidate due to duplicated names, select them with their index instead!
+* Tagging by name will partially match to **exactly one applicant** in the list ([case-insensitive](#glossary)).
+ * If multiple matches are found, a list of all matching names will be displayed:
+ - You can then enter the **full name** of the applicant you want to tag
+* Tagging by index must have a **positive** index number
+* Tags must be one of the following values, which are colour-coded as follows:
+ 1.
Rejected
+ 2.
Applicant
+ 3.
Candidate
+ 4.
Interviewee
+ 5.
Offered
+* The tag written in the command must match one of the values above ([case-insensitive](#glossary)) e.g. `t/applicant`
+* To tag with offset, the offset takes in `+` or `-`, followed by a number for the offset amount, e.g. `+1`, `-2`
+ * The tag, which represents the hiring stage the specific applicant is at, will progress/regress the hiring stage by
+ the offset amount
+ * The offset amount must range from -4 to +4
+ * The order for the hiring stages is `Rejected` > `Applicant` > `Candidate` > `Interviewee` > `Offered`
+ * The tag will not regress past `Rejected` and progress past `Offered`
+ * For example, if you enter the command `tag -4 n/John` with an applicant named John tagged as `Applicant`,
+ John's tag is set to `Rejected`
+
+
+Examples:
+* `tag n/John Doe t/Applicant` will tag `John Doe` as `Applicant` in HireHive
+
+
+
+* `tag 1 t/Candidate` will tag the 1st applicant as `Candidate`
+* `tag +1 n/John Doe` for a `John Doe` applicant with tag `Applicant` will tag them as `Candidate`
+
+[Back to top](#welcome-to-hirehive)
+
+
+### Add note to applicant: `newnote`
+
+You can add information about the applicant into a note with this command.
+
+Format: `newnote n/NAME i/NOTE`
+
+* Adds the note if the given name partially matches **exactly one** applicant in the list ([case-insensitive](#glossary))
+* If multiple matches are found, a list of all matching names will be displayed. You should then retry the command but using the **full name** of the desired applicant.
+* NOTE has a limit of 500 characters.
+* After adding, a popup window will appear containing the given input.
+* If the input is empty or consists only of whitespace, then the popup window displays a default message "Currently empty..." in yellow.
+
Examples:
-* `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01`
-* `add n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal`
+* `newnote n/John Doe i/25 years old` adds a note to John Doe that says "25 years old"
+
+
+
+* `newnote n/John Doe i/` removes any existing content in John Doe's note
+
+
:bulb: **Tip:**
+You can remove the contents of the note by leaving the NOTE field blank.
+
+
+[Back to top](#welcome-to-hirehive)
+
+### Schedule interview dates for applicants : `schedule`
-### Listing all persons : `list`
+Automatically or manually schedule your next interview with a potential candidate.
-Shows a list of all persons in the address book.
+Format:
+
+Command | Description
+--------|------------------
+`schedule n/NAME [id/DATE]` | Schedule interview date by name.
+`schedule INDEX [id/DATE]` | Schedule interview date by index.
+
+
:bulb: **Tip:**
+In the event where you are unable to select a candidate due to duplicated names, select them with their index instead!
+
+
+* The date format is DD/MM/YYYY (date/month/year) e.g. "04/04/2025"
+* The command will only accept dates starting from the current date.
+* If date is left empty, the next day that does not have an interview after the current day will be used to schedule the meeting instead.
+* Scheduling by name will partially match to **exactly one applicant** in the list ([case-insensitive](#glossary)).
+ * If multiple matches are found, a list of all matching names will be displayed
+ * You can then enter the **full name** of the applicant you want to schedule
+* You will have to provide a **positive [integer](#glossary)** to select a candidate by index.
+* Scheduling an interview with an `Applicant` or `Candidate` will automatically change their tag to an `Interviewee`.
+
+
:exclamation: **Caution:**
+You will not be allowed to schedule interviews with candidates that are already `Offered`/`Rejected`. Please change
+their tags if you wish to schedule a second interview.
+
+
+Examples:
+* Running `schedule n/John Doe id/01/01/2026` will schedule an interview with John Doe on 01/01/2026
+
+
+
+* Running `schedule n/John Doe` on 01/01/2026 when there are no interviews scheduled will schedule an interview with
+ John Doe on 02/01/2026
+* Running `schedule n/John Doe` on 01/01/2026 when there is an interview on 02/01/2026 will instead schedule the
+ interview with John Doe on 03/01/2026
+
+[Back to top](#welcome-to-hirehive)
+
+### Listing applicant information
+
+### Display note of applicant: `displaynote`
+
+You can display the note of an applicant with this command.
+
+Format: `displaynote n/NAME`
+
+* Displays the note if the given name partially matches **exactly one** applicant in the list ([case-insensitive](#glossary))
+* If multiple matches are found, a list of all matching names will be displayed. You should then retry the command but using the **full name** of the desired applicant.
+* A popup window will appear containing the applicant's note.
+* If the note is empty, then the popup window displays a default message "Currently empty..." in yellow.
+
+Examples:
+* `displaynote n/John Doe` shows John Doe's note
+
+
+
+[Back to top](#welcome-to-hirehive)
+
+### Sort applicants: `sort`
+
+Sorts the applicants displayed on your screen by interview date, in chronological order so that you can conveniently view upcoming interviews.
+
+Format: `sort`
+
+
+
+[Back to top](#welcome-to-hirehive)
+
+### List all applicants: `list`
+
+Shows you a list of all the applicants in HireHive so that you can look at an overview of all the applicants if needed.
+
+
:bulb: **Tip:**
+This command also resets any filters applied by the commands below!
+
Format: `list`
-### Editing a person : `edit`
+
-Edits an existing person in the address book.
+[Back to top](#welcome-to-hirehive)
-Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]…`
+### Filtering applicant information
-* Edits the person at the specified `INDEX`. The index refers to the index number shown in the displayed person list. The index **must be a positive integer** 1, 2, 3, …
-* At least one of the optional fields must be provided.
-* Existing values will be updated to the input values.
-* When editing tags, the existing tags of the person will be removed i.e adding of tags is not cumulative.
-* You can remove all the person’s tags by typing `t/` without
- specifying any tags after it.
+The commands below are accumulative! Using one filter command after another will apply **both** filters to the applicant list. The filters will persist until other commands are used.
+
+For example, running `filter t/interviewee` and `remind 5` will filter out all interviewees whose interviews are in 5 days.
+
+### Filter applicants by tag: `filter`
+
+You can view all your applicants with a specific tag for better organization!
+
+Format: `filter t/TAG`
+
+* The search is [case-insensitive](#glossary). e.g `applicant` will match `Applicant`
+* Only full words will be matched e.g. `Reject` will not match `Rejected`
+
+Examples:
+* `filter t/Applicant` will filter and display everyone with the `Applicant` tag in the list
+
+
+
+[Back to top](#welcome-to-hirehive)
+
+### Filtering out applicants with tag: `filterout`
+You can view all your applicants in a list **except** for those with the specified tag, for easier tracking of applicants!
+
+Format: `filterout t/TAG`
+
+* The search is [case-insensitive](#glossary). e.g `applicant` will match `Applicant`
Examples:
-* `edit 1 p/91234567 e/johndoe@example.com` Edits the phone number and email address of the 1st person to be `91234567` and `johndoe@example.com` respectively.
-* `edit 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags.
+* `filterout t/offered` will filter out all applicants that were already offered the job, the remaining list will
+ display applicants without the `Offered` tag.
+
+
+
+[Back to top](#welcome-to-hirehive)
+
+
+### Show applicants with upcoming interviews: `remind`
-### Locating persons by name: `find`
+Easily remind yourself of your upcoming interviews by listing down all applicants with interviews in the given days' time.
-Finds persons whose names contain any of the given keywords.
+Format: `remind DAYS`
+
+* `DAYS` is the number of upcoming days you wish to check for interviews for (inclusive).
+* The number of days given must be a **non-negative [integer](#glossary)**, i.e. greater or equal to 0
+
+Examples:
+
+Given that today is 08/04/2025, and you have the following interviews scheduled:
+
+- Alice Yeoh: 08/04/2025
+- Bernice Yu: 10/04/2025
+- Charlotte Oliveiro: 31/12/2025
+
+* `remind 0` will display Alice's entry
+
+
+
+* `remind 2` will display Alice's and Bob's entry
+
+[Back to top](#welcome-to-hirehive)
+
+### Find applicants by name: `find`
+You can search for applicants whose names contain any of the given keywords!
Format: `find KEYWORD [MORE_KEYWORDS]`
-* The search is case-insensitive. e.g `hans` will match `Hans`
-* The order of the keywords does not matter. e.g. `Hans Bo` will match `Bo Hans`
-* Only the name is searched.
-* Only full words will be matched e.g. `Han` will not match `Hans`
-* Persons matching at least one keyword will be returned (i.e. `OR` search).
- e.g. `Hans Bo` will return `Hans Gruber`, `Bo Yang`
+* The search follows partial name matching. e.g. `find Han` will return `Han` and `Hans`
+* The search is [case-insensitive](#glossary). e.g. `hans` will match `Hans`
+* The order of the keywords **matter**. e.g. `Hans Bo` will not match `Bo Hans`
+* Only keywords in name are searched.
+
Examples:
-* `find John` returns `john` and `John Doe`
-* `find alex david` returns `Alex Yeoh`, `David Li`
- 
+* `find John` with an applicant John Doe in the list returns `John Doe`
+
+
+
+[Back to top](#welcome-to-hirehive)
+
+### Deletion of applicants
+
+### Delete an applicant: `delete`
-### Deleting a person : `delete`
+You can delete a specific applicant from HireHive if their contact is no longer required.
-Deletes the specified person from the address book.
+Format:
-Format: `delete INDEX`
+Command | Description
+--------|------------------
+`delete n/NAME` | Delete by name.
+`delete INDEX` | Delete by index.
-* Deletes the person at the specified `INDEX`.
-* The index refers to the index number shown in the displayed person list.
-* The index **must be a positive integer** 1, 2, 3, …
+
:bulb: **Tip:**
+In the event where you are unable to select a candidate due to duplicated names, select them with their index instead!
+
+
+* Deleting by name will partially match to **exactly one applicant** in the list ([case-insensitive](#glossary)).
+ * If multiple matches are found, a list of all matching names will be displayed
+ * You can then enter the **full name** of the applicant you want to delete
+* Deleting by index must have a **positive** index number
Examples:
-* `list` followed by `delete 2` deletes the 2nd person in the address book.
-* `find Betsy` followed by `delete 1` deletes the 1st person in the results of the `find` command.
+* `delete n/John Doe` deletes John Doe's contact from HireHive
+
+
-### Clearing all entries : `clear`
+* `delete 2` deletes the second applicant in the list from HireHive
-Clears all entries from the address book.
+[Back to top](#welcome-to-hirehive)
+
+### Clear all entries : `clear`
+
+Clears all entries from HireHive.
Format: `clear`
-### Exiting the program : `exit`
+
+
+:exclamation: **Caution:**
+This action is **irreversible**! Please use this command with caution!
+
+
+
+
+**:information_source: Note:**
+If you `clear` the data in HireHive and exit the app immediately, when you re-run HireHive, you will see a message on your screen warning you that the data might be corrupted. But not to worry! You may ignore this message and continue using HireHive as per normal.
+
+
+
+
+[Back to top](#welcome-to-hirehive)
-Exits the program.
+### Exit the program : `exit`
+
+You can use this command to exit the program once you are done using it.
Format: `exit`
-### Saving the data
+[Back to top](#welcome-to-hirehive)
+
+### Save the data
+
+HireHive data is saved in the [hard disk](#glossary) automatically after any command that changes the data. If successfully saved, the output following the command will display the success message. There is no need to save manually.
-AddressBook data are saved in the hard disk automatically after any command that changes the data. There is no need to save manually.
+[Back to top](#welcome-to-hirehive)
-### Editing the data file
+### Edit the data file
-AddressBook data are saved automatically as a JSON file `[JAR file location]/data/addressbook.json`. Advanced users are welcome to update data directly by editing that data file.
+HireHive data are saved automatically as a [JSON](#glossary) file `[JAR file location]/data/addressbook.json`. Advanced users are welcome to update data directly by editing that data file.
:exclamation: **Caution:**
-If your changes to the data file makes its format invalid, AddressBook will discard all data and start with an empty data file at the next run. Hence, it is recommended to take a backup of the file before editing it.
-Furthermore, certain edits can cause the AddressBook to behave in unexpected ways (e.g., if a value entered is outside of the acceptable range). Therefore, edit the data file only if you are confident that you can update it correctly.
+If your changes to the data file makes its format **invalid**, HireHive will start with an **empty** data file at the next run. It will **discard** the old invalid data after the first successful command during this run. Hence, it is recommended to take a backup of the file before editing it.
+Furthermore, certain edits can cause HireHive to behave in unexpected ways (e.g., if a value entered is outside the acceptable range, or it is not of the expected data type). Therefore, edit the data file only if you are confident that you can update it correctly.
-### Archiving data files `[coming in v2.0]`
-
-_Details coming soon ..._
+[Back to top](#welcome-to-hirehive)
--------------------------------------------------------------------------------------------------------------------
## FAQ
-**Q**: How do I transfer my data to another Computer?
-**A**: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous AddressBook home folder.
+**Q**: How do I transfer my data to another computer?
+**A**: Install the app in the other computer and overwrite the data file it creates with the file that contains the data of your previous HireHive home folder.
+
+[Back to top](#welcome-to-hirehive)
--------------------------------------------------------------------------------------------------------------------
## Known issues
-1. **When using multiple screens**, if you move the application to a secondary screen, and later switch to using only the primary screen, the GUI will open off-screen. The remedy is to delete the `preferences.json` file created by the application before running the application again.
-2. **If you minimize the Help Window** and then run the `help` command (or use the `Help` menu, or the keyboard shortcut `F1`) again, the original Help Window will remain minimized, and no new Help Window will appear. The remedy is to manually restore the minimized Help Window.
+1. **When using multiple screens**, if you move the application to a secondary screen, and later switch to using only the primary screen, the [GUI](#glossary) will open off-screen. The remedy is to delete the `preferences.json` file created by the application before running the application again.
+2. If you **minimize the Help Window and then run the `help` command** (or use the `Help` menu, or the keyboard [shortcut](#glossary) `F1`) again, the original Help Window will remain minimized, and no new Help Window will appear. The remedy is to manually restore the minimized Help Window.
+
+[Back to top](#welcome-to-hirehive)
--------------------------------------------------------------------------------------------------------------------
-## Command summary
+## Glossary
-Action | Format, Examples
+Term | Description
--------|------------------
-**Add** | `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…` e.g., `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague`
-**Clear** | `clear`
-**Delete** | `delete INDEX` e.g., `delete 3`
-**Edit** | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]…` e.g.,`edit 2 n/James Lee e/jameslee@example.com`
-**Find** | `find KEYWORD [MORE_KEYWORDS]` e.g., `find James Jake`
-**List** | `list`
-**Help** | `help`
+**Alphanumeric** | Consisting of both letters (A to Z) and numbers (0 to 9).
+**Applicant** | A person who makes a formal application for something, especially a job.
+**Case-insensitive** | Uppercase and lowercase letters are treated the same and hence equivalent.
+**Graphical User Interface (GUI)** | A form of user interface that allows users to interact with electronic devices through graphical icons and visual indicators such as secondary notation.
+**Hard disk** | The storage device used by a computer. These can be used as primary or secondary storage.
+**Integer** | A whole number within the range of -231 and 231 inclusive.
+**JSON** | Acronym for _JavaScript Object Notation,_ an open standard file format and data interchange format that uses human-readable text to store and transmit data objects consisting of name–value pairs and arrays (or other serializable values).
+**Shortcut** | A key or combination of keys that you can press on a computer keyboard to quickly perform a specific action.
+**Unique** | Only 1 specific instance of it exists.
+
+[Back to top](#welcome-to-hirehive)
+
+--------------------------------------------------------------------------------------------------------------------
diff --git a/docs/_config.yml b/docs/_config.yml
index 6bd245d8f4e..bf406ecb908 100644
--- a/docs/_config.yml
+++ b/docs/_config.yml
@@ -1,4 +1,4 @@
-title: "AB-3"
+title: "HireHive"
theme: minima
header_pages:
diff --git a/docs/_sass/minima/_base.scss b/docs/_sass/minima/_base.scss
index 0d3f6e80ced..057c9210d37 100644
--- a/docs/_sass/minima/_base.scss
+++ b/docs/_sass/minima/_base.scss
@@ -288,7 +288,7 @@ table {
text-align: center;
}
.site-header:before {
- content: "AB-3";
+ content: "HireHive";
font-size: 32px;
}
}
diff --git a/docs/diagrams/ArchitectureSequenceDiagram.puml b/docs/diagrams/ArchitectureSequenceDiagram.puml
index 48b6cc4333c..7f15449f688 100644
--- a/docs/diagrams/ArchitectureSequenceDiagram.puml
+++ b/docs/diagrams/ArchitectureSequenceDiagram.puml
@@ -8,18 +8,23 @@ Participant ":Logic" as logic LOGIC_COLOR
Participant ":Model" as model MODEL_COLOR
Participant ":Storage" as storage STORAGE_COLOR
-user -[USER_COLOR]> ui : "delete 1"
+user -[USER_COLOR]> ui : "delete n/Alice"
activate ui UI_COLOR
-ui -[UI_COLOR]> logic : execute("delete 1")
+ui -[UI_COLOR]> logic : execute("delete n/Alice")
activate logic LOGIC_COLOR
logic -[LOGIC_COLOR]> model : deletePerson(p)
activate model MODEL_COLOR
model -[MODEL_COLOR]-> logic
+
+logic -[LOGIC_COLOR]> model : updateFilteredPersonList
+model -[MODEL_COLOR]-> logic
+
deactivate model
+
logic -[LOGIC_COLOR]> storage : saveAddressBook(addressBook)
activate storage STORAGE_COLOR
diff --git a/docs/diagrams/BetterModelClassDiagram.puml b/docs/diagrams/BetterModelClassDiagram.puml
index 598474a5c82..51f21867e0d 100644
--- a/docs/diagrams/BetterModelClassDiagram.puml
+++ b/docs/diagrams/BetterModelClassDiagram.puml
@@ -18,4 +18,6 @@ Person *--> Name
Person *--> Phone
Person *--> Email
Person *--> Address
+Person *--> Role
+Person *--> InterviewDate
@enduml
diff --git a/docs/diagrams/DeleteSequenceDiagram.puml b/docs/diagrams/DeleteSequenceDiagram.puml
index 5241e79d7da..54d875e1ace 100644
--- a/docs/diagrams/DeleteSequenceDiagram.puml
+++ b/docs/diagrams/DeleteSequenceDiagram.puml
@@ -6,20 +6,28 @@ box Logic LOGIC_COLOR_T1
participant ":LogicManager" as LogicManager LOGIC_COLOR
participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
participant ":DeleteCommandParser" as DeleteCommandParser LOGIC_COLOR
+participant ":ArgumentTokenizer" as ArgumentTokenizer LOGIC_COLOR
+participant ":ArgumentMultimap" as ArgumentMultimap LOGIC_COLOR
+participant "q:NameQuery" as NameQuery LOGIC_COLOR
participant "d:DeleteCommand" as DeleteCommand LOGIC_COLOR
+participant "<> CommandUtil" as CommandUtil LOGIC_COLOR
+participant "l:List" as ListPerson LOGIC_COLOR
participant "r:CommandResult" as CommandResult LOGIC_COLOR
end box
box Model MODEL_COLOR_T1
participant "m:Model" as Model MODEL_COLOR
+participant "n:NameContainsKeywordsPredicate" as NameContainsKeywordsPredicate MODEL_COLOR
end box
-[-> LogicManager : execute("delete 1")
+[-> LogicManager : execute("delete n/Alice")
activate LogicManager
-LogicManager -> AddressBookParser : parseCommand("delete 1")
+LogicManager -> AddressBookParser : parseCommand("delete n/Alice")
activate AddressBookParser
+create CommandUtil
+
create DeleteCommandParser
AddressBookParser -> DeleteCommandParser
activate DeleteCommandParser
@@ -27,14 +35,43 @@ activate DeleteCommandParser
DeleteCommandParser --> AddressBookParser
deactivate DeleteCommandParser
-AddressBookParser -> DeleteCommandParser : parse("1")
+AddressBookParser -> DeleteCommandParser : parse("n/Alice")
activate DeleteCommandParser
+create ArgumentTokenizer
+DeleteCommandParser -> ArgumentTokenizer : tokenize("n/Alice", PREFIX_NAME)
+activate ArgumentTokenizer
+
+create ArgumentMultimap
+ArgumentTokenizer -> ArgumentMultimap : extractArguments
+activate ArgumentMultimap
+ArgumentMultimap --> ArgumentTokenizer
+deactivate ArgumentMultimap
+ArgumentTokenizer --> DeleteCommandParser
+deactivate ArgumentTokenizer
+
+DeleteCommandParser -> ArgumentMultimap : getValue(PREFIX_NAME)
+activate ArgumentMultimap
+ArgumentMultimap --> DeleteCommandParser : "Alice"
+deactivate ArgumentMultimap
+
+create NameContainsKeywordsPredicate
+DeleteCommandParser -> NameContainsKeywordsPredicate : new NameContainsKeywordsPredicate("Alice")
+activate NameContainsKeywordsPredicate
+NameContainsKeywordsPredicate --> DeleteCommandParser : n
+deactivate NameContainsKeywordsPredicate
+
+create NameQuery
+DeleteCommandParser -> NameQuery : new(n)
+activate NameQuery
+NameQuery --> DeleteCommandParser : q
+deactivate NameQuery
+
create DeleteCommand
-DeleteCommandParser -> DeleteCommand
+DeleteCommandParser -> DeleteCommand : new DeleteCommand(q)
activate DeleteCommand
-DeleteCommand --> DeleteCommandParser :
+DeleteCommand --> DeleteCommandParser : d
deactivate DeleteCommand
DeleteCommandParser --> AddressBookParser : d
@@ -49,9 +86,33 @@ deactivate AddressBookParser
LogicManager -> DeleteCommand : execute(m)
activate DeleteCommand
-DeleteCommand -> Model : deletePerson(1)
+DeleteCommand -> CommandUtil : querySearch(m, q)
+activate CommandUtil
+
+CommandUtil -> NameQuery : query(m)
+activate NameQuery
+
+NameQuery -> Model : query(m)
activate Model
+Model -> NameContainsKeywordsPredicate : updateFilteredPersonList
+activate NameContainsKeywordsPredicate
+
+NameContainsKeywordsPredicate --> Model
+deactivate NameContainsKeywordsPredicate
+
+Model --> NameQuery : List l
+deactivate Model
+
+NameQuery -> CommandUtil : List l
+deactivate NameQuery
+CommandUtil -> DeleteCommand : Person : p
+deactivate CommandUtil
+
+DeleteCommand -> Model : deletePerson(p)
+activate Model
+Model --> DeleteCommand
+DeleteCommand -> Model : updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS)
Model --> DeleteCommand
deactivate Model
diff --git a/docs/diagrams/ModelClassDiagram.puml b/docs/diagrams/ModelClassDiagram.puml
index 0de5673070d..7af200a0772 100644
--- a/docs/diagrams/ModelClassDiagram.puml
+++ b/docs/diagrams/ModelClassDiagram.puml
@@ -19,6 +19,10 @@ Class Email
Class Name
Class Phone
Class Tag
+Class Note
+Class Role
+Class InterviewDate
+
Class I #FFFFFF
}
@@ -37,18 +41,20 @@ UserPrefs .up.|> ReadOnlyUserPrefs
AddressBook *--> "1" UniquePersonList
UniquePersonList --> "~* all" Person
-Person *--> Name
+Person *-left-> Name
Person *--> Phone
-Person *--> Email
+Person *-right-> Email
Person *--> Address
-Person *--> "*" Tag
+Person *--> Tag
+Person *--> Role
+Person *--> Note
+Person *--> InterviewDate
Person -[hidden]up--> I
UniquePersonList -[hidden]right-> I
-Name -[hidden]right-> Phone
-Phone -[hidden]right-> Address
-Address -[hidden]right-> Email
+Name -[hidden]down-> Address
+Email -[hidden]down-> InterviewDate
ModelManager --> "~* filtered" Person
@enduml
diff --git a/docs/diagrams/UiClassDiagram.puml b/docs/diagrams/UiClassDiagram.puml
index 95473d5aa19..cbe4be4c373 100644
--- a/docs/diagrams/UiClassDiagram.puml
+++ b/docs/diagrams/UiClassDiagram.puml
@@ -10,6 +10,7 @@ Class "{abstract}\nUiPart" as UiPart
Class UiManager
Class MainWindow
Class HelpWindow
+Class NoteWindow
Class ResultDisplay
Class PersonListPanel
Class PersonCard
@@ -35,6 +36,7 @@ MainWindow *-down-> "1" ResultDisplay
MainWindow *-down-> "1" PersonListPanel
MainWindow *-down-> "1" StatusBarFooter
MainWindow --> "0..1" HelpWindow
+MainWindow -> "0..1" NoteWindow
PersonListPanel -down-> "*" PersonCard
@@ -46,6 +48,7 @@ PersonListPanel --|> UiPart
PersonCard --|> UiPart
StatusBarFooter --|> UiPart
HelpWindow --|> UiPart
+NoteWindow --|> UiPart
PersonCard ..> Model
UiManager -right-> Logic
diff --git a/docs/images/BetterModelClassDiagram.png b/docs/images/BetterModelClassDiagram.png
index 02a42e35e76..ecfc59a223a 100644
Binary files a/docs/images/BetterModelClassDiagram.png and b/docs/images/BetterModelClassDiagram.png differ
diff --git a/docs/images/DeleteSequenceDiagram.png b/docs/images/DeleteSequenceDiagram.png
index ac2ae217c51..b061d95d583 100644
Binary files a/docs/images/DeleteSequenceDiagram.png and b/docs/images/DeleteSequenceDiagram.png differ
diff --git a/docs/images/ModelClassDiagram.png b/docs/images/ModelClassDiagram.png
index a19fb1b4ac8..bf5a716b7cf 100644
Binary files a/docs/images/ModelClassDiagram.png and b/docs/images/ModelClassDiagram.png differ
diff --git a/docs/images/Ui-2.png b/docs/images/Ui-2.png
new file mode 100644
index 00000000000..fd60292788b
Binary files /dev/null and b/docs/images/Ui-2.png differ
diff --git a/docs/images/Ui-AddCommand.png b/docs/images/Ui-AddCommand.png
new file mode 100644
index 00000000000..283638f200f
Binary files /dev/null and b/docs/images/Ui-AddCommand.png differ
diff --git a/docs/images/Ui-ClearCommand.png b/docs/images/Ui-ClearCommand.png
new file mode 100644
index 00000000000..02d24b0194b
Binary files /dev/null and b/docs/images/Ui-ClearCommand.png differ
diff --git a/docs/images/Ui-DeleteCommand.png b/docs/images/Ui-DeleteCommand.png
new file mode 100644
index 00000000000..cef07afc69e
Binary files /dev/null and b/docs/images/Ui-DeleteCommand.png differ
diff --git a/docs/images/Ui-DisplayNoteCommand.png b/docs/images/Ui-DisplayNoteCommand.png
new file mode 100644
index 00000000000..578edcc212f
Binary files /dev/null and b/docs/images/Ui-DisplayNoteCommand.png differ
diff --git a/docs/images/Ui-EditCommand.png b/docs/images/Ui-EditCommand.png
new file mode 100644
index 00000000000..072c5c5a0cf
Binary files /dev/null and b/docs/images/Ui-EditCommand.png differ
diff --git a/docs/images/Ui-FilterCommand.png b/docs/images/Ui-FilterCommand.png
new file mode 100644
index 00000000000..0ead25717b7
Binary files /dev/null and b/docs/images/Ui-FilterCommand.png differ
diff --git a/docs/images/Ui-FilterOutCommand.png b/docs/images/Ui-FilterOutCommand.png
new file mode 100644
index 00000000000..80779a7a89e
Binary files /dev/null and b/docs/images/Ui-FilterOutCommand.png differ
diff --git a/docs/images/Ui-FindCommand.png b/docs/images/Ui-FindCommand.png
new file mode 100644
index 00000000000..9ae5ede85e3
Binary files /dev/null and b/docs/images/Ui-FindCommand.png differ
diff --git a/docs/images/Ui-ListCommand.png b/docs/images/Ui-ListCommand.png
new file mode 100644
index 00000000000..c9b25187e8f
Binary files /dev/null and b/docs/images/Ui-ListCommand.png differ
diff --git a/docs/images/Ui-NewNoteCommand.png b/docs/images/Ui-NewNoteCommand.png
new file mode 100644
index 00000000000..fc00284e7bc
Binary files /dev/null and b/docs/images/Ui-NewNoteCommand.png differ
diff --git a/docs/images/Ui-RemindCommand.png b/docs/images/Ui-RemindCommand.png
new file mode 100644
index 00000000000..9f175779a77
Binary files /dev/null and b/docs/images/Ui-RemindCommand.png differ
diff --git a/docs/images/Ui-ScheduleCommand.png b/docs/images/Ui-ScheduleCommand.png
new file mode 100644
index 00000000000..9aeded40079
Binary files /dev/null and b/docs/images/Ui-ScheduleCommand.png differ
diff --git a/docs/images/Ui-SortCommand.png b/docs/images/Ui-SortCommand.png
new file mode 100644
index 00000000000..73c8c0332ab
Binary files /dev/null and b/docs/images/Ui-SortCommand.png differ
diff --git a/docs/images/Ui-TagCommand.png b/docs/images/Ui-TagCommand.png
new file mode 100644
index 00000000000..fa0366e414e
Binary files /dev/null and b/docs/images/Ui-TagCommand.png differ
diff --git a/docs/images/Ui.png b/docs/images/Ui.png
index 5bd77847aa2..cdf9bf2bee8 100644
Binary files a/docs/images/Ui.png and b/docs/images/Ui.png differ
diff --git a/docs/images/UiClassDiagram.png b/docs/images/UiClassDiagram.png
index 11f06d68671..5a69fd0cdb0 100644
Binary files a/docs/images/UiClassDiagram.png and b/docs/images/UiClassDiagram.png differ
diff --git a/docs/images/UpdatedArchitectureSequenceDiagram.png b/docs/images/UpdatedArchitectureSequenceDiagram.png
new file mode 100644
index 00000000000..e9e7aaf458b
Binary files /dev/null and b/docs/images/UpdatedArchitectureSequenceDiagram.png differ
diff --git a/docs/images/deannapoh.png b/docs/images/deannapoh.png
new file mode 100644
index 00000000000..d6587ed8950
Binary files /dev/null and b/docs/images/deannapoh.png differ
diff --git a/docs/images/ditzchann.png b/docs/images/ditzchann.png
new file mode 100644
index 00000000000..13e5190e0b7
Binary files /dev/null and b/docs/images/ditzchann.png differ
diff --git a/docs/images/helpMessage.png b/docs/images/helpMessage.png
index b1f70470137..6f74992dc6c 100644
Binary files a/docs/images/helpMessage.png and b/docs/images/helpMessage.png differ
diff --git a/docs/images/m0destly.png b/docs/images/m0destly.png
new file mode 100644
index 00000000000..bcd29edd143
Binary files /dev/null and b/docs/images/m0destly.png differ
diff --git a/docs/images/nat-ong555.png b/docs/images/nat-ong555.png
new file mode 100644
index 00000000000..76c92213cc6
Binary files /dev/null and b/docs/images/nat-ong555.png differ
diff --git a/docs/images/zeotheburrito.png b/docs/images/zeotheburrito.png
new file mode 100644
index 00000000000..bafb635d16a
Binary files /dev/null and b/docs/images/zeotheburrito.png differ
diff --git a/docs/img.png b/docs/img.png
new file mode 100644
index 00000000000..0bcd79ea04b
Binary files /dev/null and b/docs/img.png differ
diff --git a/docs/index.md b/docs/index.md
index 7601dbaad0d..93c9bc408b9 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -1,6 +1,6 @@
---
layout: page
-title: AddressBook Level-3
+title: HireHive
---
[](https://github.com/se-edu/addressbook-level3/actions)
@@ -8,10 +8,11 @@ title: AddressBook Level-3

-**AddressBook is a desktop application for managing your contact details.** While it has a GUI, most of the user interactions happen using a CLI (Command Line Interface).
+HireHive is your **personal, all-in-one** hiring assistant designed to simplify the hiring process so you can focus on what matters most - finding the best talent.
-* If you are interested in using AddressBook, head over to the [_Quick Start_ section of the **User Guide**](UserGuide.html#quick-start).
-* If you are interested about developing AddressBook, the [**Developer Guide**](DeveloperGuide.html) is a good place to start.
+* If you are interested in using HireHive, head over to the [_Quick Start_ section of the **User Guide**](UserGuide.html#quick-start).
+* If you are interested about developing HireHive, the [**Developer Guide**](DeveloperGuide.html) is a good place to
+ start.
**Acknowledgements**
diff --git a/docs/team/deannapoh.md b/docs/team/deannapoh.md
new file mode 100644
index 00000000000..c7bbe934948
--- /dev/null
+++ b/docs/team/deannapoh.md
@@ -0,0 +1,46 @@
+---
+layout: page
+title: Deanna's Project Portfolio Page
+---
+
+### Project: HireHive
+
+Hirehive is a applicant tracking system (ATS) designed to help businesses streamline their recruitment process. It allows companies to post job listings, track applicants, manage interviews, and collaborate with hiring teams in one centralized platform.
+
+Given below are my contributions to the project.
+
+* **New Feature**: Added the ability to undo/redo previous commands.
+ * What it does: allows the user to undo all previous commands one at a time. Preceding undo commands can be reversed by using the redo command.
+ * Justification: This feature improves the product significantly because a user can make mistakes in commands and the app should provide a convenient way to rectify them.
+ * Highlights: This enhancement affects existing commands and commands to be added in future. It required an in-depth analysis of design alternatives. The implementation too was challenging as it required changes to existing commands.
+ * Credits: *{mention here if you reused any code/ideas from elsewhere or if a third-party library is heavily used in the feature so that a reader can make a more accurate judgement of how much effort went into the feature}*
+
+* **New Feature**: Added a history command that allows the user to navigate to previous commands using up/down keys.
+
+* **Code contributed**: [RepoSense link]()
+
+* **Project management**:
+ * Managed releases `v1.3` - `v1.5rc` (3 releases) on GitHub
+
+* **Enhancements to existing features**:
+ * Updated the GUI color scheme (Pull requests [\#33](), [\#34]())
+ * Wrote additional tests for existing features to increase coverage from 88% to 92% (Pull requests [\#36](), [\#38]())
+
+* **Documentation**:
+ * User Guide:
+ * Added documentation for the features `delete` and `find` [\#72]()
+ * Did cosmetic tweaks to existing documentation of features `clear`, `exit`: [\#74]()
+ * Developer Guide:
+ * Added implementation details of the `delete` feature.
+
+* **Community**:
+ * PRs reviewed (with non-trivial review comments): [\#12](), [\#32](), [\#19](), [\#42]()
+ * Contributed to forum discussions (examples: [1](), [2](), [3](), [4]())
+ * Reported bugs and suggestions for other teams in the class (examples: [1](), [2](), [3]())
+ * Some parts of the history feature I added was adopted by several other class mates ([1](), [2]())
+
+* **Tools**:
+ * Integrated a third party library (Natty) to the project ([\#42]())
+ * Integrated a new Github plugin (CircleCI) to the team repo
+
+* _{you can add/remove categories in the list above}_
diff --git a/docs/team/ditzchann.md b/docs/team/ditzchann.md
new file mode 100644
index 00000000000..dc858bf065a
--- /dev/null
+++ b/docs/team/ditzchann.md
@@ -0,0 +1,4 @@
+---
+layout: page
+title: Ditzchann's Project Portfolio Page
+---
diff --git a/docs/team/m0destly.md b/docs/team/m0destly.md
new file mode 100644
index 00000000000..2e8aca7e30d
--- /dev/null
+++ b/docs/team/m0destly.md
@@ -0,0 +1,4 @@
+---
+layout: page
+title: m0destly's Project Portfolio Page
+---
diff --git a/docs/team/nat-ong555.md b/docs/team/nat-ong555.md
new file mode 100644
index 00000000000..0df2c32a8c5
--- /dev/null
+++ b/docs/team/nat-ong555.md
@@ -0,0 +1,8 @@
+---
+layout: page
+title: Natalie's Project Portfolio Page
+---
+
+### Project: HireHive
+
+HireHive is a desktop address book application used by hiring managers to track candidate profiles and interviews. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java.
diff --git a/docs/team/zeotheburrito.md b/docs/team/zeotheburrito.md
new file mode 100644
index 00000000000..231f339e32d
--- /dev/null
+++ b/docs/team/zeotheburrito.md
@@ -0,0 +1,4 @@
+---
+layout: page
+title: Wong Zenwei's Project Portfolio Page
+---
diff --git a/src/main/java/seedu/address/AppParameters.java b/src/main/java/hirehive/address/AppParameters.java
similarity index 91%
rename from src/main/java/seedu/address/AppParameters.java
rename to src/main/java/hirehive/address/AppParameters.java
index 3d603622d4e..5b5c9d2747c 100644
--- a/src/main/java/seedu/address/AppParameters.java
+++ b/src/main/java/hirehive/address/AppParameters.java
@@ -1,4 +1,4 @@
-package seedu.address;
+package hirehive.address;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -6,10 +6,10 @@
import java.util.Objects;
import java.util.logging.Logger;
+import hirehive.address.commons.core.LogsCenter;
+import hirehive.address.commons.util.FileUtil;
+import hirehive.address.commons.util.ToStringBuilder;
import javafx.application.Application;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.commons.util.FileUtil;
-import seedu.address.commons.util.ToStringBuilder;
/**
* Represents the parsed command-line parameters given to the application.
diff --git a/src/main/java/seedu/address/Main.java b/src/main/java/hirehive/address/Main.java
similarity index 95%
rename from src/main/java/seedu/address/Main.java
rename to src/main/java/hirehive/address/Main.java
index 9461d6da769..e5afae52614 100644
--- a/src/main/java/seedu/address/Main.java
+++ b/src/main/java/hirehive/address/Main.java
@@ -1,9 +1,9 @@
-package seedu.address;
+package hirehive.address;
import java.util.logging.Logger;
+import hirehive.address.commons.core.LogsCenter;
import javafx.application.Application;
-import seedu.address.commons.core.LogsCenter;
/**
* The main entry point to the application.
diff --git a/src/main/java/seedu/address/MainApp.java b/src/main/java/hirehive/address/MainApp.java
similarity index 84%
rename from src/main/java/seedu/address/MainApp.java
rename to src/main/java/hirehive/address/MainApp.java
index 678ddc8c218..9b9e409e576 100644
--- a/src/main/java/seedu/address/MainApp.java
+++ b/src/main/java/hirehive/address/MainApp.java
@@ -1,42 +1,41 @@
-package seedu.address;
+package hirehive.address;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
import java.util.logging.Logger;
+import hirehive.address.commons.core.Config;
+import hirehive.address.commons.core.LogsCenter;
+import hirehive.address.commons.core.Version;
+import hirehive.address.commons.exceptions.DataLoadingException;
+import hirehive.address.commons.util.ConfigUtil;
+import hirehive.address.commons.util.StringUtil;
+import hirehive.address.logic.Logic;
+import hirehive.address.logic.LogicManager;
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.ReadOnlyAddressBook;
+import hirehive.address.model.ReadOnlyUserPrefs;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.model.util.SampleDataUtil;
+import hirehive.address.storage.AddressBookStorage;
+import hirehive.address.storage.JsonAddressBookStorage;
+import hirehive.address.storage.JsonUserPrefsStorage;
+import hirehive.address.storage.Storage;
+import hirehive.address.storage.StorageManager;
+import hirehive.address.storage.UserPrefsStorage;
+import hirehive.address.ui.Ui;
+import hirehive.address.ui.UiManager;
import javafx.application.Application;
import javafx.stage.Stage;
-import seedu.address.commons.core.Config;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.commons.core.Version;
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.commons.util.ConfigUtil;
-import seedu.address.commons.util.StringUtil;
-import seedu.address.logic.Logic;
-import seedu.address.logic.LogicManager;
-import seedu.address.model.AddressBook;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.ReadOnlyUserPrefs;
-import seedu.address.model.UserPrefs;
-import seedu.address.model.util.SampleDataUtil;
-import seedu.address.storage.AddressBookStorage;
-import seedu.address.storage.JsonAddressBookStorage;
-import seedu.address.storage.JsonUserPrefsStorage;
-import seedu.address.storage.Storage;
-import seedu.address.storage.StorageManager;
-import seedu.address.storage.UserPrefsStorage;
-import seedu.address.ui.Ui;
-import seedu.address.ui.UiManager;
-
/**
* Runs the application.
*/
public class MainApp extends Application {
- public static final Version VERSION = new Version(0, 2, 2, true);
+ public static final Version VERSION = new Version(1, 3, 0, true);
private static final Logger logger = LogsCenter.getLogger(MainApp.class);
diff --git a/src/main/java/seedu/address/commons/core/Config.java b/src/main/java/hirehive/address/commons/core/Config.java
similarity index 94%
rename from src/main/java/seedu/address/commons/core/Config.java
rename to src/main/java/hirehive/address/commons/core/Config.java
index 485f85a5e05..2bac71518ab 100644
--- a/src/main/java/seedu/address/commons/core/Config.java
+++ b/src/main/java/hirehive/address/commons/core/Config.java
@@ -1,11 +1,11 @@
-package seedu.address.commons.core;
+package hirehive.address.commons.core;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.logging.Level;
-import seedu.address.commons.util.ToStringBuilder;
+import hirehive.address.commons.util.ToStringBuilder;
/**
* Config values used by the app
diff --git a/src/main/java/seedu/address/commons/core/GuiSettings.java b/src/main/java/hirehive/address/commons/core/GuiSettings.java
similarity index 96%
rename from src/main/java/seedu/address/commons/core/GuiSettings.java
rename to src/main/java/hirehive/address/commons/core/GuiSettings.java
index a97a86ee8d7..135586b7040 100644
--- a/src/main/java/seedu/address/commons/core/GuiSettings.java
+++ b/src/main/java/hirehive/address/commons/core/GuiSettings.java
@@ -1,10 +1,10 @@
-package seedu.address.commons.core;
+package hirehive.address.commons.core;
import java.awt.Point;
import java.io.Serializable;
import java.util.Objects;
-import seedu.address.commons.util.ToStringBuilder;
+import hirehive.address.commons.util.ToStringBuilder;
/**
* A Serializable class that contains the GUI settings.
diff --git a/src/main/java/seedu/address/commons/core/LogsCenter.java b/src/main/java/hirehive/address/commons/core/LogsCenter.java
similarity index 99%
rename from src/main/java/seedu/address/commons/core/LogsCenter.java
rename to src/main/java/hirehive/address/commons/core/LogsCenter.java
index 8cf8e15a0f0..4973a9b4bbc 100644
--- a/src/main/java/seedu/address/commons/core/LogsCenter.java
+++ b/src/main/java/hirehive/address/commons/core/LogsCenter.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.core;
+package hirehive.address.commons.core;
import static java.util.Objects.requireNonNull;
diff --git a/src/main/java/seedu/address/commons/core/Version.java b/src/main/java/hirehive/address/commons/core/Version.java
similarity index 98%
rename from src/main/java/seedu/address/commons/core/Version.java
rename to src/main/java/hirehive/address/commons/core/Version.java
index 491d24559b4..32000caa181 100644
--- a/src/main/java/seedu/address/commons/core/Version.java
+++ b/src/main/java/hirehive/address/commons/core/Version.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.core;
+package hirehive.address.commons.core;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
diff --git a/src/main/java/seedu/address/commons/core/index/Index.java b/src/main/java/hirehive/address/commons/core/index/Index.java
similarity index 94%
rename from src/main/java/seedu/address/commons/core/index/Index.java
rename to src/main/java/hirehive/address/commons/core/index/Index.java
index dd170d8b68d..02b438cfd56 100644
--- a/src/main/java/seedu/address/commons/core/index/Index.java
+++ b/src/main/java/hirehive/address/commons/core/index/Index.java
@@ -1,6 +1,6 @@
-package seedu.address.commons.core.index;
+package hirehive.address.commons.core.index;
-import seedu.address.commons.util.ToStringBuilder;
+import hirehive.address.commons.util.ToStringBuilder;
/**
* Represents a zero-based or one-based index.
diff --git a/src/main/java/seedu/address/commons/exceptions/DataLoadingException.java b/src/main/java/hirehive/address/commons/exceptions/DataLoadingException.java
similarity index 81%
rename from src/main/java/seedu/address/commons/exceptions/DataLoadingException.java
rename to src/main/java/hirehive/address/commons/exceptions/DataLoadingException.java
index 9904ba47afe..f65b5ca4482 100644
--- a/src/main/java/seedu/address/commons/exceptions/DataLoadingException.java
+++ b/src/main/java/hirehive/address/commons/exceptions/DataLoadingException.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.exceptions;
+package hirehive.address.commons.exceptions;
/**
* Represents an error during loading of data from a file.
diff --git a/src/main/java/seedu/address/commons/exceptions/IllegalValueException.java b/src/main/java/hirehive/address/commons/exceptions/IllegalValueException.java
similarity index 92%
rename from src/main/java/seedu/address/commons/exceptions/IllegalValueException.java
rename to src/main/java/hirehive/address/commons/exceptions/IllegalValueException.java
index 19124db485c..7e28f01a6f6 100644
--- a/src/main/java/seedu/address/commons/exceptions/IllegalValueException.java
+++ b/src/main/java/hirehive/address/commons/exceptions/IllegalValueException.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.exceptions;
+package hirehive.address.commons.exceptions;
/**
* Signals that some given data does not fulfill some constraints.
diff --git a/src/main/java/seedu/address/commons/util/AppUtil.java b/src/main/java/hirehive/address/commons/util/AppUtil.java
similarity index 94%
rename from src/main/java/seedu/address/commons/util/AppUtil.java
rename to src/main/java/hirehive/address/commons/util/AppUtil.java
index 87aa89c0326..de1873f206c 100644
--- a/src/main/java/seedu/address/commons/util/AppUtil.java
+++ b/src/main/java/hirehive/address/commons/util/AppUtil.java
@@ -1,9 +1,9 @@
-package seedu.address.commons.util;
+package hirehive.address.commons.util;
import static java.util.Objects.requireNonNull;
+import hirehive.address.MainApp;
import javafx.scene.image.Image;
-import seedu.address.MainApp;
/**
* A container for App specific utility functions
diff --git a/src/main/java/seedu/address/commons/util/CollectionUtil.java b/src/main/java/hirehive/address/commons/util/CollectionUtil.java
similarity index 96%
rename from src/main/java/seedu/address/commons/util/CollectionUtil.java
rename to src/main/java/hirehive/address/commons/util/CollectionUtil.java
index eafe4dfd681..525bd5eebee 100644
--- a/src/main/java/seedu/address/commons/util/CollectionUtil.java
+++ b/src/main/java/hirehive/address/commons/util/CollectionUtil.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.util;
+package hirehive.address.commons.util;
import static java.util.Objects.requireNonNull;
diff --git a/src/main/java/seedu/address/commons/util/ConfigUtil.java b/src/main/java/hirehive/address/commons/util/ConfigUtil.java
similarity index 76%
rename from src/main/java/seedu/address/commons/util/ConfigUtil.java
rename to src/main/java/hirehive/address/commons/util/ConfigUtil.java
index 7b829c3c4cc..59b8c1f5727 100644
--- a/src/main/java/seedu/address/commons/util/ConfigUtil.java
+++ b/src/main/java/hirehive/address/commons/util/ConfigUtil.java
@@ -1,11 +1,11 @@
-package seedu.address.commons.util;
+package hirehive.address.commons.util;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
-import seedu.address.commons.core.Config;
-import seedu.address.commons.exceptions.DataLoadingException;
+import hirehive.address.commons.core.Config;
+import hirehive.address.commons.exceptions.DataLoadingException;
/**
* A class for accessing the Config File.
diff --git a/src/main/java/seedu/address/commons/util/FileUtil.java b/src/main/java/hirehive/address/commons/util/FileUtil.java
similarity index 98%
rename from src/main/java/seedu/address/commons/util/FileUtil.java
rename to src/main/java/hirehive/address/commons/util/FileUtil.java
index b1e2767cdd9..1665ed9ebff 100644
--- a/src/main/java/seedu/address/commons/util/FileUtil.java
+++ b/src/main/java/hirehive/address/commons/util/FileUtil.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.util;
+package hirehive.address.commons.util;
import java.io.IOException;
import java.nio.file.Files;
diff --git a/src/main/java/seedu/address/commons/util/JsonUtil.java b/src/main/java/hirehive/address/commons/util/JsonUtil.java
similarity index 97%
rename from src/main/java/seedu/address/commons/util/JsonUtil.java
rename to src/main/java/hirehive/address/commons/util/JsonUtil.java
index 100cb16c395..47dc262ea2a 100644
--- a/src/main/java/seedu/address/commons/util/JsonUtil.java
+++ b/src/main/java/hirehive/address/commons/util/JsonUtil.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.util;
+package hirehive.address.commons.util;
import static java.util.Objects.requireNonNull;
@@ -20,8 +20,8 @@
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.commons.exceptions.DataLoadingException;
+import hirehive.address.commons.core.LogsCenter;
+import hirehive.address.commons.exceptions.DataLoadingException;
/**
* Converts a Java object instance to JSON and vice versa
diff --git a/src/main/java/seedu/address/commons/util/StringUtil.java b/src/main/java/hirehive/address/commons/util/StringUtil.java
similarity index 58%
rename from src/main/java/seedu/address/commons/util/StringUtil.java
rename to src/main/java/hirehive/address/commons/util/StringUtil.java
index 61cc8c9a1cb..8f5dc2f4dbe 100644
--- a/src/main/java/seedu/address/commons/util/StringUtil.java
+++ b/src/main/java/hirehive/address/commons/util/StringUtil.java
@@ -1,7 +1,7 @@
-package seedu.address.commons.util;
+package hirehive.address.commons.util;
+import static hirehive.address.commons.util.AppUtil.checkArgument;
import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.AppUtil.checkArgument;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -29,13 +29,8 @@ public static boolean containsWordIgnoreCase(String sentence, String word) {
String preppedWord = word.trim();
checkArgument(!preppedWord.isEmpty(), "Word parameter cannot be empty");
- checkArgument(preppedWord.split("\\s+").length == 1, "Word parameter should be a single word");
- String preppedSentence = sentence;
- String[] wordsInPreppedSentence = preppedSentence.split("\\s+");
-
- return Arrays.stream(wordsInPreppedSentence)
- .anyMatch(preppedWord::equalsIgnoreCase);
+ return sentence.toLowerCase().contains(preppedWord.toLowerCase());
}
/**
@@ -65,4 +60,40 @@ public static boolean isNonZeroUnsignedInteger(String s) {
return false;
}
}
+
+ /**
+ * Returns true if {@code s} represents a 0 or positive integer
+ * e.g. 0, 1, 2, 3, ..., {@code Integer.MAX_VALUE}
+ * Will return false for any other non-null string input
+ * e.g. empty string, "-1", "+1", and " 2 " (untrimmed), "3 0" (contains whitespace), "1 a" (contains letters)
+ * @throws NullPointerException if {@code s} is null.
+ */
+ public static boolean isPositiveInteger(String s) {
+ requireNonNull(s);
+
+ try {
+ int value = Integer.parseInt(s);
+ return value >= 0 && !s.startsWith("+"); // "+1" is successfully parsed by Integer#parseInt(String)
+ } catch (NumberFormatException nfe) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if {@code s} represents a string or a valid integer
+ * @throws NullPointerException if {@code s} is null.
+ */
+ public static boolean isValidStringOrInteger(String s) {
+ requireNonNull(s);
+ if (s.matches("-?\\d+")) {
+ try {
+ long num = Long.parseLong(s);
+ return num >= Integer.MIN_VALUE && num <= Integer.MAX_VALUE;
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ }
}
diff --git a/src/main/java/seedu/address/commons/util/ToStringBuilder.java b/src/main/java/hirehive/address/commons/util/ToStringBuilder.java
similarity index 97%
rename from src/main/java/seedu/address/commons/util/ToStringBuilder.java
rename to src/main/java/hirehive/address/commons/util/ToStringBuilder.java
index d979b926734..c1304e23538 100644
--- a/src/main/java/seedu/address/commons/util/ToStringBuilder.java
+++ b/src/main/java/hirehive/address/commons/util/ToStringBuilder.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.util;
+package hirehive.address.commons.util;
/**
* Builds a string representation of an object that is suitable as the return value of {@link Object#toString()}.
diff --git a/src/main/java/seedu/address/logic/Logic.java b/src/main/java/hirehive/address/logic/Logic.java
similarity index 66%
rename from src/main/java/seedu/address/logic/Logic.java
rename to src/main/java/hirehive/address/logic/Logic.java
index 92cd8fa605a..f5023654ec8 100644
--- a/src/main/java/seedu/address/logic/Logic.java
+++ b/src/main/java/hirehive/address/logic/Logic.java
@@ -1,14 +1,16 @@
-package seedu.address.logic;
+package hirehive.address.logic;
import java.nio.file.Path;
+import hirehive.address.commons.core.GuiSettings;
+import hirehive.address.logic.commands.CommandResult;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.Model;
+import hirehive.address.model.ReadOnlyAddressBook;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
import javafx.collections.ObservableList;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.logic.commands.CommandResult;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.person.Person;
/**
* API of the Logic component
@@ -26,7 +28,7 @@ public interface Logic {
/**
* Returns the AddressBook.
*
- * @see seedu.address.model.Model#getAddressBook()
+ * @see Model#getAddressBook()
*/
ReadOnlyAddressBook getAddressBook();
@@ -47,4 +49,7 @@ public interface Logic {
* Set the user prefs' GUI settings.
*/
void setGuiSettings(GuiSettings guiSettings);
+
+ Note getPersonNote();
+ int getFilteredPersonListSize();
}
diff --git a/src/main/java/seedu/address/logic/LogicManager.java b/src/main/java/hirehive/address/logic/LogicManager.java
similarity index 74%
rename from src/main/java/seedu/address/logic/LogicManager.java
rename to src/main/java/hirehive/address/logic/LogicManager.java
index 5aa3b91c7d0..f92a542048e 100644
--- a/src/main/java/seedu/address/logic/LogicManager.java
+++ b/src/main/java/hirehive/address/logic/LogicManager.java
@@ -1,22 +1,23 @@
-package seedu.address.logic;
+package hirehive.address.logic;
import java.io.IOException;
import java.nio.file.AccessDeniedException;
import java.nio.file.Path;
import java.util.logging.Logger;
+import hirehive.address.commons.core.GuiSettings;
+import hirehive.address.commons.core.LogsCenter;
+import hirehive.address.logic.commands.Command;
+import hirehive.address.logic.commands.CommandResult;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.parser.AddressBookParser;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.Model;
+import hirehive.address.model.ReadOnlyAddressBook;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
+import hirehive.address.storage.Storage;
import javafx.collections.ObservableList;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.logic.commands.Command;
-import seedu.address.logic.commands.CommandResult;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.logic.parser.AddressBookParser;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.Model;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.person.Person;
-import seedu.address.storage.Storage;
/**
* The main LogicManager of the app.
@@ -85,4 +86,13 @@ public GuiSettings getGuiSettings() {
public void setGuiSettings(GuiSettings guiSettings) {
model.setGuiSettings(guiSettings);
}
+
+ @Override
+ public Note getPersonNote() {
+ return model.getPersonNote();
+ }
+ @Override
+ public int getFilteredPersonListSize() {
+ return model.getListSize();
+ }
}
diff --git a/src/main/java/hirehive/address/logic/Messages.java b/src/main/java/hirehive/address/logic/Messages.java
new file mode 100644
index 00000000000..8faf51aa1f1
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/Messages.java
@@ -0,0 +1,76 @@
+package hirehive.address.logic;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import hirehive.address.logic.parser.Prefix;
+import hirehive.address.model.person.Person;
+
+/**
+ * Container for user visible messages.
+ */
+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_PERSON_DISPLAYED_INDEX = "The provided index is invalid. ";
+ public static final String MESSAGE_INDEX_OUT_OF_BOUNDS = "The provided index is out of bounds."
+ + "\n Please enter a number between 1 and %d";
+ public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!";
+ public static final String MESSAGE_DUPLICATE_FIELDS =
+ "Multiple values specified for the following single-valued field(s): ";
+ public static final String MESSAGE_NO_SUCH_PERSON = "No such person exists.";
+
+ public static final String MESSAGE_MULTIPLE_PEOPLE_QUERIED = "There are multiple contacts containing the given name."
+ + "\n Please enter the full name of the person, or use their index if other people have the same name";
+
+ public static final String MESSAGE_MULTIPLE_PEOPLE_QUERIED_NAME = "There are multiple contacts containing the given name."
+ + "\n Please enter the full name of the person.";
+
+ public static final String MESSAGE_FILTER_OVERVIEW_TAG = "Showing %s entries.";
+ public static final String MESSAGE_FILTER_OVERVIEW_DATE = "Showing entries with interviews in %1$d days.";
+ public static final String MESSAGE_FILTER_OVERVIEW_NAME = "Showing entries with keywords %s in name.";
+ public static final String MESSAGE_FILTEROUT_OVERVIEW_TAG = "Showing all entries without %s tag.";
+ public static final String MESSAGE_EMPTY_ADDRESS_BOOK = "Current address book is empty. This might be due to corrupted data."
+ + "\nWARNING: Please check if data/addressbook.json has old corrupted data and attempt to fix it, otherwise any new successful commands will overwrite those contents.";
+ public static final String MESSAGE_SAMPLE_ADDRESS_BOOK = "Success: Sample applicant data has been loaded successfully.";
+ public static final String MESSAGE_LOAD_SUCCESS = "Success: Applicant data has been loaded successfully.";
+ public static final String MESSAGE_DATA_SAVED = "\nSuccess: Applicant data has been saved.";
+
+ /**
+ * Returns an error message indicating the duplicate prefixes.
+ */
+ public static String getErrorMessageForDuplicatePrefixes(Prefix... duplicatePrefixes) {
+ assert duplicatePrefixes.length > 0;
+
+ Set duplicateFields =
+ Stream.of(duplicatePrefixes).map(Prefix::toString).collect(Collectors.toSet());
+
+ return MESSAGE_DUPLICATE_FIELDS + String.join(" ", duplicateFields);
+ }
+
+ /**
+ * Formats the {@code person} for display to the user.
+ */
+ public static String format(Person person) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(person.getName())
+ .append("; Phone: ")
+ .append(person.getPhone())
+ .append("; Email: ")
+ .append(person.getEmail())
+ .append("; Address: ")
+ .append(person.getAddress())
+ .append("; Role: ")
+ .append(person.getRole())
+ .append("; Date: ")
+ .append(person.getDate())
+ .append("; Tag: ")
+ .append(person.getTag())
+ .append("; Note: ")
+ .append(person.getNote().isEmpty() ? "Empty" : "Not empty");
+ return builder.toString();
+ }
+
+}
diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/hirehive/address/logic/commands/AddCommand.java
similarity index 68%
rename from src/main/java/seedu/address/logic/commands/AddCommand.java
rename to src/main/java/hirehive/address/logic/commands/AddCommand.java
index 5d7185a9680..11d4314d65b 100644
--- a/src/main/java/seedu/address/logic/commands/AddCommand.java
+++ b/src/main/java/hirehive/address/logic/commands/AddCommand.java
@@ -1,17 +1,19 @@
-package seedu.address.logic.commands;
+package hirehive.address.logic.commands;
+import static hirehive.address.logic.Messages.MESSAGE_DATA_SAVED;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_EMAIL;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_PHONE;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_ROLE;
import static java.util.Objects.requireNonNull;
-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_PHONE;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
-
-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.person.Person;
+
+import hirehive.address.commons.util.ToStringBuilder;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.Person;
+
/**
* Adds a person to the address book.
@@ -20,23 +22,22 @@ public class AddCommand extends Command {
public static final String COMMAND_WORD = "add";
- public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a person to the address book. "
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a person to HireHive.\n"
+ "Parameters: "
+ PREFIX_NAME + "NAME "
+ PREFIX_PHONE + "PHONE "
+ PREFIX_EMAIL + "EMAIL "
+ PREFIX_ADDRESS + "ADDRESS "
- + "[" + PREFIX_TAG + "TAG]...\n"
+ + PREFIX_ROLE + "ROLE\n"
+ "Example: " + COMMAND_WORD + " "
+ PREFIX_NAME + "John Doe "
+ PREFIX_PHONE + "98765432 "
+ PREFIX_EMAIL + "johnd@example.com "
+ PREFIX_ADDRESS + "311, Clementi Ave 2, #02-25 "
- + PREFIX_TAG + "friends "
- + PREFIX_TAG + "owesMoney";
+ + PREFIX_ROLE + "Software Engineer";
public static final String MESSAGE_SUCCESS = "New person added: %1$s";
- public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book";
+ public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in HireHive";
private final Person toAdd;
@@ -57,7 +58,7 @@ public CommandResult execute(Model model) throws CommandException {
}
model.addPerson(toAdd);
- return new CommandResult(String.format(MESSAGE_SUCCESS, Messages.format(toAdd)));
+ return new CommandResult(String.format(MESSAGE_SUCCESS, Messages.format(toAdd)), true);
}
@Override
diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/hirehive/address/logic/commands/ClearCommand.java
similarity index 63%
rename from src/main/java/seedu/address/logic/commands/ClearCommand.java
rename to src/main/java/hirehive/address/logic/commands/ClearCommand.java
index 9c86b1fa6e4..6d743aa33b4 100644
--- a/src/main/java/seedu/address/logic/commands/ClearCommand.java
+++ b/src/main/java/hirehive/address/logic/commands/ClearCommand.java
@@ -1,9 +1,10 @@
-package seedu.address.logic.commands;
+package hirehive.address.logic.commands;
+import static hirehive.address.logic.Messages.MESSAGE_DATA_SAVED;
import static java.util.Objects.requireNonNull;
-import seedu.address.model.AddressBook;
-import seedu.address.model.Model;
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.Model;
/**
* Clears the address book.
@@ -18,6 +19,6 @@ public class ClearCommand extends Command {
public CommandResult execute(Model model) {
requireNonNull(model);
model.setAddressBook(new AddressBook());
- return new CommandResult(MESSAGE_SUCCESS);
+ return new CommandResult(MESSAGE_SUCCESS, true);
}
}
diff --git a/src/main/java/seedu/address/logic/commands/Command.java b/src/main/java/hirehive/address/logic/commands/Command.java
similarity index 77%
rename from src/main/java/seedu/address/logic/commands/Command.java
rename to src/main/java/hirehive/address/logic/commands/Command.java
index 64f18992160..28d0a55a501 100644
--- a/src/main/java/seedu/address/logic/commands/Command.java
+++ b/src/main/java/hirehive/address/logic/commands/Command.java
@@ -1,7 +1,7 @@
-package seedu.address.logic.commands;
+package hirehive.address.logic.commands;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.model.Model;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.model.Model;
/**
* Represents a command with hidden internal logic and the ability to be executed.
diff --git a/src/main/java/seedu/address/logic/commands/CommandResult.java b/src/main/java/hirehive/address/logic/commands/CommandResult.java
similarity index 65%
rename from src/main/java/seedu/address/logic/commands/CommandResult.java
rename to src/main/java/hirehive/address/logic/commands/CommandResult.java
index 249b6072d0d..0d9ea2b0c1f 100644
--- a/src/main/java/seedu/address/logic/commands/CommandResult.java
+++ b/src/main/java/hirehive/address/logic/commands/CommandResult.java
@@ -1,10 +1,10 @@
-package seedu.address.logic.commands;
+package hirehive.address.logic.commands;
import static java.util.Objects.requireNonNull;
import java.util.Objects;
-import seedu.address.commons.util.ToStringBuilder;
+import hirehive.address.commons.util.ToStringBuilder;
/**
* Represents the result of a command execution.
@@ -19,13 +19,21 @@ public class CommandResult {
/** The application should exit. */
private final boolean exit;
+ /** Note window should be displayed to the user. */
+ private final boolean showNote;
+
+ /** Saved message should appear to the user */
+ private final boolean isChange;
+
/**
* Constructs a {@code CommandResult} with the specified fields.
*/
- public CommandResult(String feedbackToUser, boolean showHelp, boolean exit) {
+ public CommandResult(String feedbackToUser, boolean showHelp, boolean exit, boolean showNote, boolean isChange) {
this.feedbackToUser = requireNonNull(feedbackToUser);
this.showHelp = showHelp;
this.exit = exit;
+ this.showNote = showNote;
+ this.isChange = isChange;
}
/**
@@ -33,7 +41,11 @@ public CommandResult(String feedbackToUser, boolean showHelp, boolean exit) {
* and other fields set to their default value.
*/
public CommandResult(String feedbackToUser) {
- this(feedbackToUser, false, false);
+ this(feedbackToUser, false, false, false, false);
+ }
+
+ public CommandResult(String feedbackToUser, boolean isChange) {
+ this(feedbackToUser, false, false, false, isChange);
}
public String getFeedbackToUser() {
@@ -48,6 +60,14 @@ public boolean isExit() {
return exit;
}
+ public boolean isShowNote() {
+ return showNote;
+ }
+
+ public boolean isChange() {
+ return isChange;
+ }
+
@Override
public boolean equals(Object other) {
if (other == this) {
@@ -62,7 +82,9 @@ public boolean equals(Object other) {
CommandResult otherCommandResult = (CommandResult) other;
return feedbackToUser.equals(otherCommandResult.feedbackToUser)
&& showHelp == otherCommandResult.showHelp
- && exit == otherCommandResult.exit;
+ && exit == otherCommandResult.exit
+ && showNote == otherCommandResult.showNote
+ && isChange == otherCommandResult.isChange;
}
@Override
@@ -76,6 +98,8 @@ public String toString() {
.add("feedbackToUser", feedbackToUser)
.add("showHelp", showHelp)
.add("exit", exit)
+ .add("showNote", showNote)
+ .add("isChange", isChange)
.toString();
}
diff --git a/src/main/java/hirehive/address/logic/commands/CommandUtil.java b/src/main/java/hirehive/address/logic/commands/CommandUtil.java
new file mode 100644
index 00000000000..99a8e4675ad
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/commands/CommandUtil.java
@@ -0,0 +1,78 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.Messages.MESSAGE_MULTIPLE_PEOPLE_QUERIED;
+import static hirehive.address.logic.commands.EditCommand.createEditedPerson;
+import static java.util.Objects.requireNonNull;
+
+import java.util.List;
+
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.logic.commands.queries.exceptions.QueryException;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.person.PersonPredicate;
+
+/**
+ * Helper functions for handling command execution of similar types
+ */
+public class CommandUtil {
+
+ /**
+ * Updates the displayed list based on the given {@code predicate} and returns a CommandResult indicating
+ * the results of the filter.
+ * @param model The model to update the list in
+ * @param predicate The given predicate to filter the list with
+ * @return A CommandResult object
+ */
+ public static CommandResult executeFilter(Model model, PersonPredicate predicate) {
+ requireNonNull(model);
+ model.updateFilteredPersonList(predicate);
+ String message;
+ if (!model.getFilteredPersonList().isEmpty()) {
+ message = predicate.getSuccessString();
+ } else {
+ message = Messages.MESSAGE_NO_SUCH_PERSON;
+ }
+ return new CommandResult(message);
+ }
+
+ /**
+ * Uses the given query to find the matching person in the model.
+ * @param model The model to update the list in
+ * @param query The {@code NameQuery} object used to search for the person
+ * @return A {@code Person} object
+ * @throws CommandException
+ */
+ public static Person querySearch(Model model, NameQuery query) throws CommandException {
+ requireNonNull(model);
+ List personToEdit;
+ try {
+ personToEdit = query.query(model);
+ } catch (QueryException qe) {
+ throw new CommandException(qe.getMessage());
+ }
+ if (personToEdit.size() > 1) {
+ throw new CommandException(MESSAGE_MULTIPLE_PEOPLE_QUERIED);
+ }
+ return personToEdit.get(0);
+ }
+ /**
+ * Uses the given index to find the matching person in the model.
+ * @param model The model to update the list in
+ * @param index The {@code index} object used to search for the person
+ * @return A {@code Person} object
+ * @throws CommandException
+ */
+ public static Person indexSearch(Model model, Index index) throws CommandException {
+ List lastShownList = model.getFilteredPersonList();
+
+ if (index.getZeroBased() >= lastShownList.size()) {
+ throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
+ }
+
+ return lastShownList.get(index.getZeroBased());
+ }
+}
diff --git a/src/main/java/hirehive/address/logic/commands/DeleteCommand.java b/src/main/java/hirehive/address/logic/commands/DeleteCommand.java
new file mode 100644
index 00000000000..b0471847be1
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/commands/DeleteCommand.java
@@ -0,0 +1,100 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.Messages.MESSAGE_DATA_SAVED;
+import static hirehive.address.logic.Messages.MESSAGE_MULTIPLE_PEOPLE_QUERIED;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static java.util.Objects.isNull;
+import static java.util.Objects.requireNonNull;
+
+import java.util.List;
+import java.util.Objects;
+
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.logic.commands.queries.exceptions.QueryException;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.Person;
+
+
+/**
+ * Deletes a person identified using its displayed index from the address book.
+ */
+public class DeleteCommand extends Command {
+
+ public static final String COMMAND_WORD = "delete";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD
+ + ": Deletes the person identified by the given name or index.\n"
+ + "Parameters (either 1 or 2): \n"
+ + " 1. " + PREFIX_NAME + "NAME\n"
+ + " 2. INDEX (must be a positive integer)\n"
+ + "Example:\n"
+ + " - " + COMMAND_WORD + " " + PREFIX_NAME + "John Doe\n"
+ + " - " + COMMAND_WORD + " " + "1";
+
+ public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s";
+
+ private NameQuery query = null;
+
+ private Index index = null;
+
+ /**
+ * Creates DeleteCommand to remove a person with specified name
+ * @param query the name of the person to be deleted
+ */
+ public DeleteCommand(NameQuery query) {
+ requireNonNull(query);
+ this.query = query;
+ }
+
+ /**
+ * Creates DeleteCommand to remove a person at the specified index
+ * @param index the specified index of the Person
+ */
+ public DeleteCommand(Index index) {
+ requireNonNull(index);
+ this.index = index;
+ }
+
+ /**
+ * Executes the delete command to remove a contact from the address book
+ * @param model {@code Model} which the command should operate on.
+ * @return A {@code CommandResult} containing success message
+ * @throws CommandException if provided index is out of bounds
+ */
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+
+ Person personToDelete;
+ if (!isNull(query)) {
+ personToDelete = CommandUtil.querySearch(model, query);
+ } else if (!isNull(index)) {
+ personToDelete = CommandUtil.indexSearch(model, index);
+ } else {
+ throw new CommandException(String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE));
+ }
+
+ model.deletePerson(personToDelete);
+ model.unfilterPersonList();
+ return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, Messages.format(personToDelete)), true);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof DeleteCommand)) {
+ return false;
+ }
+
+ DeleteCommand otherDeleteCommand = (DeleteCommand) other;
+ return Objects.equals(this.query, otherDeleteCommand.query);
+ }
+
+}
diff --git a/src/main/java/hirehive/address/logic/commands/DisplayNoteCommand.java b/src/main/java/hirehive/address/logic/commands/DisplayNoteCommand.java
new file mode 100644
index 00000000000..5d67c89cb3c
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/commands/DisplayNoteCommand.java
@@ -0,0 +1,102 @@
+package hirehive.address.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.List;
+import java.util.Objects;
+
+import hirehive.address.commons.util.ToStringBuilder;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.logic.commands.queries.exceptions.QueryException;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.Name;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.model.person.Person;
+
+/**
+ * Finds a Person by name and displays the note in a popup window.
+ */
+public class DisplayNoteCommand extends Command {
+
+ public static final String COMMAND_WORD = "displaynote";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD
+ + ": Displays the note of the person identified by the name used in the displayed person list.\n"
+ + "Parameters: n/NAME\nExample: " + COMMAND_WORD + " n/john doe";
+
+ public static final String MESSAGE_SUCCESS = "Displaying note of: %1$s";
+
+ private final String name;
+
+ /**
+ * Creates DisplayNoteCommand to show the note of a person.
+ * @param name the name of the person.
+ */
+ public DisplayNoteCommand(String name) {
+ requireNonNull(name);
+ this.name = name;
+ }
+
+ /**
+ * Executes the displaynote command to display the note of the queried person
+ * @param model {@code Model} which the command should operate on.
+ * @return A {@code CommandResult} containing success message.
+ * @throws CommandException if person is not found.
+ */
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+
+ NameQuery query = new NameQuery(new NameContainsKeywordsPredicate(name));
+ List personToDisplay;
+ try {
+ personToDisplay = query.query(model);
+ } catch (QueryException e) {
+ throw new CommandException(Messages.MESSAGE_NO_SUCH_PERSON);
+ }
+
+ Person personDisplayed = null;
+ if (personToDisplay.size() > 1) {
+ Name givenName = new Name(name);
+ for (Person person : personToDisplay) {
+ if (person.getName().equals(givenName)) {
+ personDisplayed = person;
+ break;
+ }
+ }
+ if (personDisplayed == null) {
+ throw new CommandException(Messages.MESSAGE_MULTIPLE_PEOPLE_QUERIED_NAME);
+ }
+ } else {
+ personDisplayed = personToDisplay.get(0);
+ }
+
+ model.updatePersonNote(personDisplayed);
+ return new CommandResult(String.format(MESSAGE_SUCCESS, Messages.format(personDisplayed)), false,
+ false, true, false);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof DisplayNoteCommand)) {
+ return false;
+ }
+
+ DisplayNoteCommand otherNoteCommand = (DisplayNoteCommand) other;
+ return name.equals(otherNoteCommand.name);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("name", name)
+ .toString();
+ }
+}
diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/hirehive/address/logic/commands/EditCommand.java
similarity index 58%
rename from src/main/java/seedu/address/logic/commands/EditCommand.java
rename to src/main/java/hirehive/address/logic/commands/EditCommand.java
index 4b581c7331e..a58666c80d7 100644
--- a/src/main/java/seedu/address/logic/commands/EditCommand.java
+++ b/src/main/java/hirehive/address/logic/commands/EditCommand.java
@@ -1,12 +1,15 @@
-package seedu.address.logic.commands;
-
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.Messages.MESSAGE_DATA_SAVED;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_DATE;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_EMAIL;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NOTE;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_PHONE;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_ROLE;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_TAG;
import static java.util.Objects.requireNonNull;
-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_PHONE;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
-import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS;
import java.util.Collections;
import java.util.HashSet;
@@ -15,18 +18,21 @@
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.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.commons.util.CollectionUtil;
+import hirehive.address.commons.util.ToStringBuilder;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.Address;
+import hirehive.address.model.person.Email;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.Name;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.person.Phone;
+import hirehive.address.model.person.Role;
+import hirehive.address.model.tag.Tag;
/**
* Edits the details of an existing person in the address book.
@@ -43,7 +49,10 @@ public class EditCommand extends Command {
+ "[" + PREFIX_PHONE + "PHONE] "
+ "[" + PREFIX_EMAIL + "EMAIL] "
+ "[" + PREFIX_ADDRESS + "ADDRESS] "
- + "[" + PREFIX_TAG + "TAG]...\n"
+ + "[" + PREFIX_ROLE + "ROLE] "
+ + "[" + PREFIX_TAG + "TAG] "
+ + "[" + PREFIX_NOTE + "NOTE]"
+ + "[" + PREFIX_DATE + "DATE]\n"
+ "Example: " + COMMAND_WORD + " 1 "
+ PREFIX_PHONE + "91234567 "
+ PREFIX_EMAIL + "johndoe@example.com";
@@ -84,24 +93,54 @@ public CommandResult execute(Model model) throws CommandException {
}
model.setPerson(personToEdit, editedPerson);
- model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
- return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson)));
+ model.unfilterPersonList();
+ model.updatePersonNote(editedPerson);
+ return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson)), true);
}
/**
* Creates and returns a {@code Person} with the details of {@code personToEdit}
* edited with {@code editPersonDescriptor}.
*/
- private static Person createEditedPerson(Person personToEdit, EditPersonDescriptor editPersonDescriptor) {
+ protected static Person createEditedPerson(Person personToEdit, EditPersonDescriptor editPersonDescriptor) {
assert personToEdit != null;
Name updatedName = editPersonDescriptor.getName().orElse(personToEdit.getName());
Phone updatedPhone = editPersonDescriptor.getPhone().orElse(personToEdit.getPhone());
Email updatedEmail = editPersonDescriptor.getEmail().orElse(personToEdit.getEmail());
Address updatedAddress = editPersonDescriptor.getAddress().orElse(personToEdit.getAddress());
- Set updatedTags = editPersonDescriptor.getTags().orElse(personToEdit.getTags());
+ Role updatedRole = editPersonDescriptor.getRole().orElse(personToEdit.getRole());
+ Tag updatedTag = editPersonDescriptor.getTag().orElse(personToEdit.getTag());
+ Note updatedNote = editPersonDescriptor.getNote().orElse(personToEdit.getNote());
+ InterviewDate updatedDate = editPersonDescriptor.getDate().orElse(personToEdit.getDate());
+
+ return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedRole, updatedTag,
+ updatedNote, updatedDate);
+ }
+
+ protected static Person createOffsetTagPerson(Person personToEdit, int offset) {
+ assert personToEdit != null;
+
+ Name name = personToEdit.getName();
+ Phone phone = personToEdit.getPhone();
+ Email email = personToEdit.getEmail();
+ Address address = personToEdit.getAddress();
+ Role role = personToEdit.getRole();
+ Note note = personToEdit.getNote();
+ InterviewDate date = personToEdit.getDate();
- return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags);
+ Tag updatedTag = personToEdit.getTag().offsetBy(offset);
+
+ return new Person(name, phone, email, address, role, updatedTag,
+ note, date);
+ }
+
+ protected Index getIndex() {
+ return index;
+ }
+
+ protected EditPersonDescriptor getEditPersonDescriptor() {
+ return editPersonDescriptor;
}
@Override
@@ -137,27 +176,33 @@ public static class EditPersonDescriptor {
private Phone phone;
private Email email;
private Address address;
- private Set tags;
+ private Role role;
+ private Tag tag;
+ private Note note;
+ private InterviewDate date;
public EditPersonDescriptor() {}
/**
* Copy constructor.
- * A defensive copy of {@code tags} is used internally.
+ * A defensive copy of {@code tag} is used internally.
*/
public EditPersonDescriptor(EditPersonDescriptor toCopy) {
setName(toCopy.name);
setPhone(toCopy.phone);
setEmail(toCopy.email);
setAddress(toCopy.address);
- setTags(toCopy.tags);
+ setRole(toCopy.role);
+ setTag(toCopy.tag);
+ setNote(toCopy.note);
+ setDate(toCopy.date);
}
/**
* Returns true if at least one field is edited.
*/
public boolean isAnyFieldEdited() {
- return CollectionUtil.isAnyNonNull(name, phone, email, address, tags);
+ return CollectionUtil.isAnyNonNull(name, phone, email, address, role, tag, note, date);
}
public void setName(Name name) {
@@ -192,21 +237,45 @@ public Optional getAddress() {
return Optional.ofNullable(address);
}
+ public void setRole(Role role) {
+ this.role = role;
+ }
+
+ public Optional getRole() {
+ return Optional.ofNullable(role);
+ }
+
+ public void setNote(Note note) {
+ this.note = note;
+ }
+
+ public Optional getNote() {
+ return Optional.ofNullable(note);
+ }
+
+ public void setDate(InterviewDate date) {
+ this.date = date;
+ }
+
+ public Optional getDate() {
+ return Optional.ofNullable(date);
+ }
+
/**
- * Sets {@code tags} to this object's {@code tags}.
- * A defensive copy of {@code tags} is used internally.
+ * Sets {@code tag} to this object's {@code tag}.
+ * A defensive copy of {@code tag} is used internally.
*/
- public void setTags(Set tags) {
- this.tags = (tags != null) ? new HashSet<>(tags) : null;
+ public void setTag(Tag tag) {
+ this.tag = tag;
}
/**
* Returns an unmodifiable tag set, which throws {@code UnsupportedOperationException}
* if modification is attempted.
- * Returns {@code Optional#empty()} if {@code tags} is null.
+ * Returns {@code Optional#empty()} if {@code tag} is null.
*/
- public Optional> getTags() {
- return (tags != null) ? Optional.of(Collections.unmodifiableSet(tags)) : Optional.empty();
+ public Optional getTag() {
+ return Optional.ofNullable(tag);
}
@Override
@@ -225,7 +294,10 @@ public boolean equals(Object other) {
&& Objects.equals(phone, otherEditPersonDescriptor.phone)
&& Objects.equals(email, otherEditPersonDescriptor.email)
&& Objects.equals(address, otherEditPersonDescriptor.address)
- && Objects.equals(tags, otherEditPersonDescriptor.tags);
+ && Objects.equals(role, otherEditPersonDescriptor.role)
+ && Objects.equals(tag, otherEditPersonDescriptor.tag)
+ && Objects.equals(note, otherEditPersonDescriptor.note)
+ && Objects.equals(date, otherEditPersonDescriptor.date);
}
@Override
@@ -235,7 +307,10 @@ public String toString() {
.add("phone", phone)
.add("email", email)
.add("address", address)
- .add("tags", tags)
+ .add("role", role)
+ .add("tag", tag)
+ .add("note", note)
+ .add("interviewDate", date)
.toString();
}
}
diff --git a/src/main/java/seedu/address/logic/commands/ExitCommand.java b/src/main/java/hirehive/address/logic/commands/ExitCommand.java
similarity index 78%
rename from src/main/java/seedu/address/logic/commands/ExitCommand.java
rename to src/main/java/hirehive/address/logic/commands/ExitCommand.java
index 3dd85a8ba90..03621a1ef96 100644
--- a/src/main/java/seedu/address/logic/commands/ExitCommand.java
+++ b/src/main/java/hirehive/address/logic/commands/ExitCommand.java
@@ -1,6 +1,6 @@
-package seedu.address.logic.commands;
+package hirehive.address.logic.commands;
-import seedu.address.model.Model;
+import hirehive.address.model.Model;
/**
* Terminates the program.
@@ -13,7 +13,7 @@ public class ExitCommand extends Command {
@Override
public CommandResult execute(Model model) {
- return new CommandResult(MESSAGE_EXIT_ACKNOWLEDGEMENT, false, true);
+ return new CommandResult(MESSAGE_EXIT_ACKNOWLEDGEMENT, false, true, false, false);
}
}
diff --git a/src/main/java/hirehive/address/logic/commands/FilterCommand.java b/src/main/java/hirehive/address/logic/commands/FilterCommand.java
new file mode 100644
index 00000000000..8130f385332
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/commands/FilterCommand.java
@@ -0,0 +1,54 @@
+package hirehive.address.logic.commands;
+
+import hirehive.address.commons.util.ToStringBuilder;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.parser.CliSyntax;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.PersonContainsTagPredicate;
+
+/**
+ * Finds and lists all persons in address book whose tags contain any of the argument tags.
+ * Tag matching is case-insensitive.
+ */
+public class FilterCommand extends Command {
+ public static final String COMMAND_WORD = "filter";
+ public static final String NOT_IMPLEMENTED_TEXT = "Command not implemented yet";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Filters all persons with the given tag "
+ + "(case-insensitive) and displays them as a list with index numbers.\n"
+ + "Parameters: t/TAG\n"
+ + "Example: " + COMMAND_WORD + " " + CliSyntax.PREFIX_TAG + "applicant";
+
+ private final PersonContainsTagPredicate predicate;
+
+ public FilterCommand(PersonContainsTagPredicate predicate) {
+ this.predicate = predicate;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ return CommandUtil.executeFilter(model, predicate);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof FilterCommand)) {
+ return false;
+ }
+
+ FilterCommand otherFilterCommand = (FilterCommand) other;
+ return predicate.equals(otherFilterCommand.predicate);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("predicate", predicate)
+ .toString();
+ }
+}
diff --git a/src/main/java/hirehive/address/logic/commands/FilterOutCommand.java b/src/main/java/hirehive/address/logic/commands/FilterOutCommand.java
new file mode 100644
index 00000000000..4130d76ee30
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/commands/FilterOutCommand.java
@@ -0,0 +1,48 @@
+package hirehive.address.logic.commands;
+
+import hirehive.address.logic.parser.CliSyntax;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.PersonDoesNotContainTagPredicate;
+
+/**
+ * Finds and lists all persons in address book whose tags do not
+ * contain any of the argument tags.
+ */
+public class FilterOutCommand extends Command {
+ public static final String COMMAND_WORD = "filterout";
+ public static final String MESSAGE_USAGE = COMMAND_WORD
+ + ": Filters out all persons with the given tag (case-insensitive) "
+ + "and displays the remaining persons as a list.\n"
+ + "Parameters: t/TAG\n"
+ + "Example: " + COMMAND_WORD + " " + CliSyntax.PREFIX_TAG + "offered";
+
+ private final PersonDoesNotContainTagPredicate predicate;
+
+ /**
+ * Creates FilterOutCommand to filter out applicants with the specified tag
+ * @param predicate the predicate to filter the list
+ */
+ public FilterOutCommand(PersonDoesNotContainTagPredicate predicate) {
+ this.predicate = predicate;
+ }
+
+ @Override
+ public CommandResult execute(Model model) {
+ return CommandUtil.executeFilter(model, predicate);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof FilterOutCommand)) {
+ return false;
+ }
+
+ FilterOutCommand otherFilterOutCommand = (FilterOutCommand) other;
+ return predicate.equals(otherFilterOutCommand.predicate);
+ }
+}
diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/hirehive/address/logic/commands/FindCommand.java
similarity index 73%
rename from src/main/java/seedu/address/logic/commands/FindCommand.java
rename to src/main/java/hirehive/address/logic/commands/FindCommand.java
index 72b9eddd3a7..97b2bcb52b0 100644
--- a/src/main/java/seedu/address/logic/commands/FindCommand.java
+++ b/src/main/java/hirehive/address/logic/commands/FindCommand.java
@@ -1,15 +1,14 @@
-package seedu.address.logic.commands;
+package hirehive.address.logic.commands;
import static java.util.Objects.requireNonNull;
-import seedu.address.commons.util.ToStringBuilder;
-import seedu.address.logic.Messages;
-import seedu.address.model.Model;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.commons.util.ToStringBuilder;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
/**
* Finds and lists all persons in address book whose name contains any of the argument keywords.
- * Keyword matching is case insensitive.
+ * Keyword matching is case-insensitive.
*/
public class FindCommand extends Command {
@@ -28,10 +27,7 @@ public FindCommand(NameContainsKeywordsPredicate predicate) {
@Override
public CommandResult execute(Model model) {
- requireNonNull(model);
- model.updateFilteredPersonList(predicate);
- return new CommandResult(
- String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size()));
+ return CommandUtil.executeFilter(model, predicate);
}
@Override
diff --git a/src/main/java/seedu/address/logic/commands/HelpCommand.java b/src/main/java/hirehive/address/logic/commands/HelpCommand.java
similarity index 72%
rename from src/main/java/seedu/address/logic/commands/HelpCommand.java
rename to src/main/java/hirehive/address/logic/commands/HelpCommand.java
index bf824f91bd0..fd44708507c 100644
--- a/src/main/java/seedu/address/logic/commands/HelpCommand.java
+++ b/src/main/java/hirehive/address/logic/commands/HelpCommand.java
@@ -1,6 +1,6 @@
-package seedu.address.logic.commands;
+package hirehive.address.logic.commands;
-import seedu.address.model.Model;
+import hirehive.address.model.Model;
/**
* Format full help instructions for every command for display.
@@ -16,6 +16,7 @@ public class HelpCommand extends Command {
@Override
public CommandResult execute(Model model) {
- return new CommandResult(SHOWING_HELP_MESSAGE, true, false);
+ return new CommandResult(SHOWING_HELP_MESSAGE, true,
+ false, false, false);
}
}
diff --git a/src/main/java/seedu/address/logic/commands/ListCommand.java b/src/main/java/hirehive/address/logic/commands/ListCommand.java
similarity index 66%
rename from src/main/java/seedu/address/logic/commands/ListCommand.java
rename to src/main/java/hirehive/address/logic/commands/ListCommand.java
index 84be6ad2596..d7a364b4658 100644
--- a/src/main/java/seedu/address/logic/commands/ListCommand.java
+++ b/src/main/java/hirehive/address/logic/commands/ListCommand.java
@@ -1,9 +1,9 @@
-package seedu.address.logic.commands;
+package hirehive.address.logic.commands;
+import static hirehive.address.model.Model.PREDICATE_SHOW_ALL_PERSONS;
import static java.util.Objects.requireNonNull;
-import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS;
-import seedu.address.model.Model;
+import hirehive.address.model.Model;
/**
* Lists all persons in the address book to the user.
@@ -12,13 +12,13 @@ public class ListCommand extends Command {
public static final String COMMAND_WORD = "list";
- public static final String MESSAGE_SUCCESS = "Listed all persons";
+ public static final String MESSAGE_SUCCESS = "Listed all persons.";
@Override
public CommandResult execute(Model model) {
requireNonNull(model);
- model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
+ model.unfilterPersonList();
return new CommandResult(MESSAGE_SUCCESS);
}
}
diff --git a/src/main/java/hirehive/address/logic/commands/NewNoteCommand.java b/src/main/java/hirehive/address/logic/commands/NewNoteCommand.java
new file mode 100644
index 00000000000..1cf31e5174d
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/commands/NewNoteCommand.java
@@ -0,0 +1,112 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.Messages.MESSAGE_DATA_SAVED;
+import static hirehive.address.logic.commands.EditCommand.createEditedPerson;
+import static java.util.Objects.requireNonNull;
+
+import java.util.List;
+
+import hirehive.address.commons.util.ToStringBuilder;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.EditCommand.EditPersonDescriptor;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.logic.commands.queries.exceptions.QueryException;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.Name;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.model.person.Person;
+
+/**
+ * Finds a Person by name, then creates and displays the note in a pop up window.
+ */
+public class NewNoteCommand extends Command {
+
+ public static final String COMMAND_WORD = "newnote";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD
+ + ": Creates a note for the person identified by the name used in the displayed person list. \n"
+ + "Parameters: n/NAME i/NOTE\nExample: " + COMMAND_WORD + " n/john doe i/Good at expressing himself";
+
+ public static final String MESSAGE_SUCCESS = "Added and displaying note of: %1$s";
+
+ private final String name;
+ private final EditPersonDescriptor editPersonDescriptor;
+
+ /**
+ * Creates NewnoteCommand to create and show the note of a person.
+ * @param name the name of the person.
+ */
+ public NewNoteCommand(String name, EditPersonDescriptor editPersonDescriptor) {
+ requireNonNull(name);
+ requireNonNull(editPersonDescriptor);
+
+ this.name = name;
+ this.editPersonDescriptor = editPersonDescriptor;
+ }
+
+ /**
+ * Executes the newnote command to add and display the note of the queried person
+ * @param model {@code Model} which the command should operate on.
+ * @return A {@code CommandResult} containing success message.
+ * @throws CommandException if person is not found.
+ */
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+ NameQuery query = new NameQuery(new NameContainsKeywordsPredicate(name));
+ List personToAddNote;
+ try {
+ personToAddNote = query.query(model);
+ } catch (QueryException e) {
+ throw new CommandException(Messages.MESSAGE_NO_SUCH_PERSON);
+ }
+
+ Person personAddedNote = null;
+ if (personToAddNote.size() > 1) {
+ Name givenName = new Name(name);
+ for (Person person : personToAddNote) {
+ if (person.getName().equals(givenName)) {
+ personAddedNote = person;
+ break;
+ }
+ }
+ if (personAddedNote == null) {
+ throw new CommandException(Messages.MESSAGE_MULTIPLE_PEOPLE_QUERIED_NAME);
+ }
+ } else {
+ personAddedNote = personToAddNote.get(0);
+ }
+
+ Person editedPerson = createEditedPerson(personAddedNote, editPersonDescriptor);
+
+ model.setPerson(personAddedNote, editedPerson);
+ model.updatePersonNote(editedPerson);
+ return new CommandResult(String.format(MESSAGE_SUCCESS, Messages.format(editedPerson)),
+ false, false, true, true);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof NewNoteCommand)) {
+ return false;
+ }
+
+ NewNoteCommand otherNewNoteCommand = (NewNoteCommand) other;
+ return name.equals(otherNewNoteCommand.name)
+ && editPersonDescriptor.equals(otherNewNoteCommand.editPersonDescriptor);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("name", name)
+ .add("editPersonDescriptor", editPersonDescriptor)
+ .toString();
+ }
+}
diff --git a/src/main/java/hirehive/address/logic/commands/ReminderCommand.java b/src/main/java/hirehive/address/logic/commands/ReminderCommand.java
new file mode 100644
index 00000000000..d7700e69676
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/commands/ReminderCommand.java
@@ -0,0 +1,52 @@
+package hirehive.address.logic.commands;
+
+import hirehive.address.commons.util.ToStringBuilder;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.UpcomingInterviewPredicate;
+
+/**
+ * Finds and lists all persons in address book whose interviews are coming up within a number of days.
+ * Filter is start and end date-inclusive.
+ */
+public class ReminderCommand extends Command {
+ public static final String COMMAND_WORD = "remind";
+ public static final String NOT_IMPLEMENTED_TEXT = "Command not implemented yet";
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Filters all persons with an upcoming interview "
+ + "within the given amount of days and displays them as a list with index numbers.\n"
+ + "Parameters: DAYS (must be a non-negative integer)\n"
+ + "Example: " + COMMAND_WORD + " 3";
+
+ private final UpcomingInterviewPredicate predicate;
+
+ public ReminderCommand(UpcomingInterviewPredicate predicate) {
+ this.predicate = predicate;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ return CommandUtil.executeFilter(model, predicate);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof ReminderCommand)) {
+ return false;
+ }
+
+ ReminderCommand otherReminderCommand = (ReminderCommand) other;
+ return predicate.equals(otherReminderCommand.predicate);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("predicate", predicate)
+ .toString();
+ }
+}
diff --git a/src/main/java/hirehive/address/logic/commands/ScheduleCommand.java b/src/main/java/hirehive/address/logic/commands/ScheduleCommand.java
new file mode 100644
index 00000000000..332060a993b
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/commands/ScheduleCommand.java
@@ -0,0 +1,142 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.commands.EditCommand.createEditedPerson;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_DATE;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_TAG;
+import static java.util.Objects.requireNonNull;
+
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.tag.Tag;
+
+/**
+ * Adds or edits the interview date of a Person
+ */
+public class ScheduleCommand extends Command {
+ public static final String COMMAND_WORD = "schedule";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD
+ + ": Adds or edits the interview date for the person identified by the name used in\n"
+ + "the displayed person list.\n"
+ + "If no date is specified, the next available date starting from the next day will be used instead.\n"
+ + "Parameters (either 1 or 2):\n"
+ + " 1. " + PREFIX_NAME + "NAME [" + PREFIX_DATE + "DATE]\n"
+ + " 2. INDEX [" + PREFIX_DATE + "NAME]\n"
+ + "Example:\n - " + COMMAND_WORD + " " + PREFIX_NAME + "John " + PREFIX_DATE + "01/05/2025\n"
+ + " - " + COMMAND_WORD + " 1 " + PREFIX_DATE + "01/05/2025";
+
+ public static final String MESSAGE_DATE_PERSON_SUCCESS = "Added interview date: %1$s";
+ public static final String MESSAGE_INVALID_PERSON = "%1$s has invalid tag: %2$s.\n"
+ + "You can only schedule interviews with people who are Applicants, Candidates or Interviewees.";
+ public static final String MESSAGE_NOT_IMPLEMENTED_YET =
+ "Date command not implemented yet";
+
+ private final NameQuery query;
+ private final EditCommand.EditPersonDescriptor editPersonDescriptor;
+ private final Index index;
+
+ private final boolean bDateProvided;
+
+ /**
+ * Creates a {@code ScheduleCommand} object with a provided date.
+ */
+ public ScheduleCommand(NameQuery query, EditCommand.EditPersonDescriptor editPersonDescriptor) {
+ requireNonNull(query);
+ requireNonNull(editPersonDescriptor);
+ this.query = query;
+ this.editPersonDescriptor = editPersonDescriptor;
+ this.index = null;
+ bDateProvided = true;
+ }
+
+ /**
+ * Creates a {@code ScheduleCommand} object without a provided date.
+ */
+ public ScheduleCommand(NameQuery query) {
+ requireNonNull(query);
+ this.query = query;
+ this.editPersonDescriptor = new EditCommand.EditPersonDescriptor();
+ this.index = null;
+ bDateProvided = false;
+ }
+
+ /**
+ * Creates a {@code ScheduleCommand} object with a provided date.
+ */
+ public ScheduleCommand(Index index, EditCommand.EditPersonDescriptor editPersonDescriptor) {
+ requireNonNull(index);
+ requireNonNull(editPersonDescriptor);
+ this.index = index;
+ this.query = null;
+ this.editPersonDescriptor = editPersonDescriptor;
+ bDateProvided = true;
+ }
+
+ /**
+ * Creates a {@code ScheduleCommand} object without a provided date.
+ */
+ public ScheduleCommand(Index index) {
+ requireNonNull(index);
+ this.index = index;
+ this.query = null;
+ this.editPersonDescriptor = new EditCommand.EditPersonDescriptor();
+ bDateProvided = false;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+ if (!bDateProvided) {
+ editPersonDescriptor.setDate(model.getAvailableDate());
+ }
+
+ Person personToAddDate;
+ if (index == null) {
+ personToAddDate = CommandUtil.querySearch(model, query);
+ } else {
+ personToAddDate = CommandUtil.indexSearch(model, index);
+ }
+
+ if (personToAddDate.getTag().equals(Tag.APPLICANT) || personToAddDate.getTag().equals(Tag.CANDIDATE)) {
+ editPersonDescriptor.setTag(Tag.INTERVIEWEE);
+ } else if (personToAddDate.getTag().equals(Tag.OFFERED) || personToAddDate.getTag().equals(Tag.REJECTED)) {
+ throw new CommandException(String.format(MESSAGE_INVALID_PERSON, personToAddDate.getName().toString(),
+ personToAddDate.getTag().getTagName()));
+ }
+ Person editedPerson = createEditedPerson(personToAddDate, editPersonDescriptor);
+ model.setPerson(personToAddDate, editedPerson);
+ model.unfilterPersonList();
+ model.updateFilteredPersonList(new NameContainsKeywordsPredicate(editedPerson.getName().fullName));
+ return new CommandResult(String.format(MESSAGE_DATE_PERSON_SUCCESS, Messages.format(editedPerson)), true);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof ScheduleCommand)) {
+ return false;
+ }
+
+ ScheduleCommand otherCommand = (ScheduleCommand) other;
+ if (!this.editPersonDescriptor.equals(otherCommand.editPersonDescriptor)) {
+ return false;
+ }
+ if (this.query == null) {
+ return this.index.equals(otherCommand.index) && otherCommand.query == null;
+ }
+ if (this.index == null) {
+ return this.query.equals(otherCommand.query) && otherCommand.index == null;
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/hirehive/address/logic/commands/SortCommand.java b/src/main/java/hirehive/address/logic/commands/SortCommand.java
new file mode 100644
index 00000000000..afebdca285f
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/commands/SortCommand.java
@@ -0,0 +1,22 @@
+package hirehive.address.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+
+import hirehive.address.model.Model;
+
+/**
+ * Sorts the applicants by their interview date
+ */
+public class SortCommand extends Command {
+ public static final String COMMAND_WORD = "sort";
+ public static final String MESSAGE_SUCCESS = "Applicants have been sorted by their interview date!";
+
+ @Override
+ public CommandResult execute(Model model) {
+ requireNonNull(model);
+ model.sortPersons();
+ return new CommandResult(MESSAGE_SUCCESS);
+ }
+
+
+}
diff --git a/src/main/java/hirehive/address/logic/commands/TagCommand.java b/src/main/java/hirehive/address/logic/commands/TagCommand.java
new file mode 100644
index 00000000000..8c655218be2
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/commands/TagCommand.java
@@ -0,0 +1,131 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.Messages.MESSAGE_MULTIPLE_PEOPLE_QUERIED;
+import static hirehive.address.logic.commands.EditCommand.createEditedPerson;
+import static hirehive.address.logic.commands.EditCommand.createOffsetTagPerson;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_TAG;
+import static java.util.Objects.isNull;
+import static java.util.Objects.requireNonNull;
+
+import java.util.List;
+
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.EditCommand.EditPersonDescriptor;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.logic.commands.queries.exceptions.QueryException;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.Person;
+
+/**
+ * Tags a person identified using their name or by index.
+ */
+public class TagCommand extends Command {
+
+ public static final String COMMAND_WORD = "tag";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD
+ + ": Tags the person identified by the given name or index.\n"
+ + "Parameters (either 1, 2, 3):\n"
+ + " 1. " + PREFIX_NAME + "NAME " + PREFIX_TAG + "TAG\n"
+ + " 2. OFFSET " + PREFIX_NAME + "NAME\n"
+ + " 3. INDEX (must be a positive integer) " + PREFIX_TAG + "TAG\n"
+ + "Example:\n"
+ + " - " + COMMAND_WORD + " " + PREFIX_NAME + "John " + PREFIX_TAG + "Applicant\n"
+ + " - " + COMMAND_WORD + " +1 " + PREFIX_NAME + "John\n"
+ + " - " + COMMAND_WORD + " 1 " + PREFIX_TAG + "Applicant\n";
+
+ public static final String MESSAGE_TAG_INVALID_PARAMS = "The given Tag parameters are invalid.";
+ public static final String MESSAGE_TAG_INVALID_OFFSET = "The given offset is invalid. It should range from -4 to "
+ + "+4.";
+ public static final String MESSAGE_TAG_PERSON_SUCCESS = "Tagged Person: %1$s";
+
+ private NameQuery query = null;
+ private EditPersonDescriptor editPersonDescriptor = null;
+ private Index index = null;
+ private int offset = 0;
+
+ /**
+ * @param query to query for the specific person by name
+ * @param editPersonDescriptor details to tag the person with
+ */
+ public TagCommand(NameQuery query, EditCommand.EditPersonDescriptor editPersonDescriptor) {
+ requireNonNull(query);
+ requireNonNull(editPersonDescriptor);
+
+ this.query = query;
+ this.editPersonDescriptor = editPersonDescriptor;
+ }
+
+ /**
+ * @param query to query for the specific person by name
+ * @param offset of the hiring stage tag from the person's tag
+ */
+ public TagCommand(NameQuery query, int offset) {
+ requireNonNull(query);
+
+ this.query = query;
+ this.offset = offset;
+ }
+
+ /**
+ * @param index of the person in the filtered person list to tag
+ * @param editPersonDescriptor details to tag the person with
+ */
+ public TagCommand(Index index, EditCommand.EditPersonDescriptor editPersonDescriptor) {
+ requireNonNull(index);
+ requireNonNull(editPersonDescriptor);
+
+ this.index = index;
+ this.editPersonDescriptor = editPersonDescriptor;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+ Person personToTag;
+
+ if (isNull(index)) {
+ if (isNull(editPersonDescriptor)) {
+ personToTag = CommandUtil.querySearch(model, query);
+ Person taggedPerson = createOffsetTagPerson(personToTag, offset);
+
+ model.setPerson(personToTag, taggedPerson);
+ return new CommandResult(String.format(MESSAGE_TAG_PERSON_SUCCESS, Messages.format(taggedPerson)));
+ }
+
+ personToTag = CommandUtil.querySearch(model, query);
+ Person taggedPerson = createEditedPerson(personToTag, editPersonDescriptor);
+
+ model.setPerson(personToTag, taggedPerson);
+ return new CommandResult(String.format(MESSAGE_TAG_PERSON_SUCCESS, Messages.format(taggedPerson)));
+ }
+ if (isNull(query)) {
+ personToTag = CommandUtil.indexSearch(model, index);
+ Person taggedPerson = createEditedPerson(personToTag, editPersonDescriptor);
+
+ model.setPerson(personToTag, taggedPerson);
+ return new CommandResult(String.format(MESSAGE_TAG_PERSON_SUCCESS, Messages.format(taggedPerson)));
+ }
+
+ throw new CommandException(MESSAGE_TAG_INVALID_PARAMS);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof TagCommand)) {
+ return false;
+ }
+
+ TagCommand otherTagCommand = (TagCommand) other;
+ return query.equals(otherTagCommand.query)
+ && editPersonDescriptor.equals(otherTagCommand.editPersonDescriptor);
+ }
+}
diff --git a/src/main/java/seedu/address/logic/commands/exceptions/CommandException.java b/src/main/java/hirehive/address/logic/commands/exceptions/CommandException.java
similarity index 89%
rename from src/main/java/seedu/address/logic/commands/exceptions/CommandException.java
rename to src/main/java/hirehive/address/logic/commands/exceptions/CommandException.java
index a16bd14f2cd..f3d342007b8 100644
--- a/src/main/java/seedu/address/logic/commands/exceptions/CommandException.java
+++ b/src/main/java/hirehive/address/logic/commands/exceptions/CommandException.java
@@ -1,4 +1,4 @@
-package seedu.address.logic.commands.exceptions;
+package hirehive.address.logic.commands.exceptions;
/**
* Represents an error which occurs during execution of a {@link Command}.
diff --git a/src/main/java/hirehive/address/logic/commands/queries/NameQuery.java b/src/main/java/hirehive/address/logic/commands/queries/NameQuery.java
new file mode 100644
index 00000000000..95d645ba915
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/commands/queries/NameQuery.java
@@ -0,0 +1,46 @@
+package hirehive.address.logic.commands.queries;
+
+import static hirehive.address.logic.Messages.MESSAGE_NO_SUCH_PERSON;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Predicate;
+
+import hirehive.address.logic.commands.queries.exceptions.QueryException;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.Person;
+
+/**
+ * Queries for a person by a given name.
+ */
+public class NameQuery extends Query {
+ /**
+ * @param predicate to query a model with to get a person
+ */
+ public NameQuery(Predicate predicate) {
+ super(predicate);
+ }
+
+ @Override
+ public List query(Model model) throws QueryException {
+ model.unfilterPersonList();
+ model.updateFilteredPersonList(this.predicate);
+ List filteredList = model.getFilteredPersonList();
+ if (filteredList.isEmpty()) {
+ throw new QueryException(MESSAGE_NO_SUCH_PERSON);
+ }
+ return filteredList;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (other == null || getClass() != other.getClass()) {
+ return false;
+ }
+ NameQuery nameQuery = (NameQuery) other;
+ return Objects.equals(this.predicate, nameQuery.predicate);
+ }
+}
diff --git a/src/main/java/hirehive/address/logic/commands/queries/Query.java b/src/main/java/hirehive/address/logic/commands/queries/Query.java
new file mode 100644
index 00000000000..e75182631c6
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/commands/queries/Query.java
@@ -0,0 +1,30 @@
+package hirehive.address.logic.commands.queries;
+
+import java.util.List;
+import java.util.function.Predicate;
+
+import hirehive.address.logic.commands.queries.exceptions.QueryException;
+import hirehive.address.model.Model;
+
+/**
+ * Represents a query with hidden predicate to query with
+ */
+public abstract class Query {
+ protected final Predicate predicate;
+
+ /**
+ * @param predicate to query a model with to get a result
+ */
+ public Query(Predicate predicate) {
+ this.predicate = predicate;
+ }
+
+ /**
+ * Queries the model with specified predicate and returns a specific object instance based
+ *
+ * @param model {@code Model} which the query should operate on.
+ * @return queried result from using the predicate
+ * @throws QueryException If an error occurs during query.
+ */
+ public abstract List query(Model model) throws QueryException;
+}
diff --git a/src/main/java/hirehive/address/logic/commands/queries/exceptions/QueryException.java b/src/main/java/hirehive/address/logic/commands/queries/exceptions/QueryException.java
new file mode 100644
index 00000000000..08eff964c9e
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/commands/queries/exceptions/QueryException.java
@@ -0,0 +1,14 @@
+package hirehive.address.logic.commands.queries.exceptions;
+
+/**
+ * Represents an error encountered by from a query.
+ */
+public class QueryException extends Exception {
+ public QueryException(String message) {
+ super(message);
+ }
+
+ public QueryException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/hirehive/address/logic/parser/AddCommandParser.java
similarity index 52%
rename from src/main/java/seedu/address/logic/parser/AddCommandParser.java
rename to src/main/java/hirehive/address/logic/parser/AddCommandParser.java
index 4ff1a97ed77..13855989f8d 100644
--- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java
+++ b/src/main/java/hirehive/address/logic/parser/AddCommandParser.java
@@ -1,23 +1,25 @@
-package seedu.address.logic.parser;
+package hirehive.address.logic.parser;
-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_EMAIL;
-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_TAG;
+import static hirehive.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_EMAIL;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NOTE;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_PHONE;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_ROLE;
-import java.util.Set;
import java.util.stream.Stream;
-import seedu.address.logic.commands.AddCommand;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
+import hirehive.address.logic.commands.AddCommand;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.Address;
+import hirehive.address.model.person.Email;
+import hirehive.address.model.person.Name;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.person.Phone;
+import hirehive.address.model.person.Role;
+import hirehive.address.model.tag.Tag;
/**
* Parses input arguments and creates a new AddCommand object
@@ -31,21 +33,22 @@ public class AddCommandParser implements Parser {
*/
public AddCommand parse(String args) throws ParseException {
ArgumentMultimap argMultimap =
- ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG);
+ ArgumentTokenizer.tokenize(
+ args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_ROLE);
- if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ADDRESS, PREFIX_PHONE, PREFIX_EMAIL)
+ if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ADDRESS, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ROLE)
|| !argMultimap.getPreamble().isEmpty()) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));
}
- argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS);
+ argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_ROLE);
Name name = ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get());
Phone phone = ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get());
Email email = ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get());
Address address = ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get());
- Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG));
+ Role role = ParserUtil.parseRole(argMultimap.getValue(PREFIX_ROLE).get());
- Person person = new Person(name, phone, email, address, tagList);
+ Person person = Person.createDefaultPerson(name, phone, email, address, role);
return new AddCommand(person);
}
@@ -57,5 +60,4 @@ public AddCommand parse(String args) throws ParseException {
private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
}
-
}
diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/hirehive/address/logic/parser/AddressBookParser.java
similarity index 54%
rename from src/main/java/seedu/address/logic/parser/AddressBookParser.java
rename to src/main/java/hirehive/address/logic/parser/AddressBookParser.java
index 3149ee07e0b..1fa7ea341ed 100644
--- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java
+++ b/src/main/java/hirehive/address/logic/parser/AddressBookParser.java
@@ -1,23 +1,32 @@
-package seedu.address.logic.parser;
+package hirehive.address.logic.parser;
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.Messages.MESSAGE_UNKNOWN_COMMAND;
+import static hirehive.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static hirehive.address.logic.Messages.MESSAGE_UNKNOWN_COMMAND;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.logic.commands.AddCommand;
-import seedu.address.logic.commands.ClearCommand;
-import seedu.address.logic.commands.Command;
-import seedu.address.logic.commands.DeleteCommand;
-import seedu.address.logic.commands.EditCommand;
-import seedu.address.logic.commands.ExitCommand;
-import seedu.address.logic.commands.FindCommand;
-import seedu.address.logic.commands.HelpCommand;
-import seedu.address.logic.commands.ListCommand;
-import seedu.address.logic.parser.exceptions.ParseException;
+import hirehive.address.commons.core.LogsCenter;
+import hirehive.address.logic.commands.AddCommand;
+import hirehive.address.logic.commands.ClearCommand;
+import hirehive.address.logic.commands.Command;
+import hirehive.address.logic.commands.DeleteCommand;
+import hirehive.address.logic.commands.DisplayNoteCommand;
+import hirehive.address.logic.commands.EditCommand;
+import hirehive.address.logic.commands.ExitCommand;
+import hirehive.address.logic.commands.FilterCommand;
+import hirehive.address.logic.commands.FilterOutCommand;
+import hirehive.address.logic.commands.FindCommand;
+import hirehive.address.logic.commands.HelpCommand;
+import hirehive.address.logic.commands.ListCommand;
+import hirehive.address.logic.commands.NewNoteCommand;
+import hirehive.address.logic.commands.ReminderCommand;
+import hirehive.address.logic.commands.ScheduleCommand;
+import hirehive.address.logic.commands.SortCommand;
+import hirehive.address.logic.commands.TagCommand;
+import hirehive.address.logic.parser.exceptions.ParseException;
+
/**
* Parses user input.
@@ -62,6 +71,9 @@ public Command parseCommand(String userInput) throws ParseException {
case DeleteCommand.COMMAND_WORD:
return new DeleteCommandParser().parse(arguments);
+ case TagCommand.COMMAND_WORD:
+ return new TagCommandParser().parse(arguments);
+
case ClearCommand.COMMAND_WORD:
return new ClearCommand();
@@ -77,6 +89,26 @@ public Command parseCommand(String userInput) throws ParseException {
case HelpCommand.COMMAND_WORD:
return new HelpCommand();
+ case ScheduleCommand.COMMAND_WORD:
+ return new ScheduleCommandParser().parse(arguments);
+
+ case FilterCommand.COMMAND_WORD:
+ return new FilterCommandParser().parse(arguments);
+
+ case ReminderCommand.COMMAND_WORD:
+ return new ReminderCommandParser().parse(arguments);
+
+ case SortCommand.COMMAND_WORD:
+ return new SortCommand();
+
+ case DisplayNoteCommand.COMMAND_WORD:
+ return new DisplayNoteCommandParser().parse(arguments);
+
+ case NewNoteCommand.COMMAND_WORD:
+ return new NewNoteCommandParser().parse(arguments);
+
+ case FilterOutCommand.COMMAND_WORD:
+ return new FilterOutCommandParser().parse(arguments);
default:
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
diff --git a/src/main/java/seedu/address/logic/parser/ArgumentMultimap.java b/src/main/java/hirehive/address/logic/parser/ArgumentMultimap.java
similarity index 95%
rename from src/main/java/seedu/address/logic/parser/ArgumentMultimap.java
rename to src/main/java/hirehive/address/logic/parser/ArgumentMultimap.java
index 21e26887a83..11682b7357e 100644
--- a/src/main/java/seedu/address/logic/parser/ArgumentMultimap.java
+++ b/src/main/java/hirehive/address/logic/parser/ArgumentMultimap.java
@@ -1,4 +1,4 @@
-package seedu.address.logic.parser;
+package hirehive.address.logic.parser;
import java.util.ArrayList;
import java.util.HashMap;
@@ -7,8 +7,8 @@
import java.util.Optional;
import java.util.stream.Stream;
-import seedu.address.logic.Messages;
-import seedu.address.logic.parser.exceptions.ParseException;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.parser.exceptions.ParseException;
/**
* Stores mapping of prefixes to their respective arguments.
diff --git a/src/main/java/seedu/address/logic/parser/ArgumentTokenizer.java b/src/main/java/hirehive/address/logic/parser/ArgumentTokenizer.java
similarity index 99%
rename from src/main/java/seedu/address/logic/parser/ArgumentTokenizer.java
rename to src/main/java/hirehive/address/logic/parser/ArgumentTokenizer.java
index 5c9aebfa488..399dc15c75e 100644
--- a/src/main/java/seedu/address/logic/parser/ArgumentTokenizer.java
+++ b/src/main/java/hirehive/address/logic/parser/ArgumentTokenizer.java
@@ -1,4 +1,4 @@
-package seedu.address.logic.parser;
+package hirehive.address.logic.parser;
import java.util.ArrayList;
import java.util.Arrays;
diff --git a/src/main/java/seedu/address/logic/parser/CliSyntax.java b/src/main/java/hirehive/address/logic/parser/CliSyntax.java
similarity index 67%
rename from src/main/java/seedu/address/logic/parser/CliSyntax.java
rename to src/main/java/hirehive/address/logic/parser/CliSyntax.java
index 75b1a9bf119..e45cebdee2f 100644
--- a/src/main/java/seedu/address/logic/parser/CliSyntax.java
+++ b/src/main/java/hirehive/address/logic/parser/CliSyntax.java
@@ -1,4 +1,4 @@
-package seedu.address.logic.parser;
+package hirehive.address.logic.parser;
/**
* Contains Command Line Interface (CLI) syntax definitions common to multiple commands
@@ -10,6 +10,8 @@ public class CliSyntax {
public static final Prefix PREFIX_PHONE = new Prefix("p/");
public static final Prefix PREFIX_EMAIL = new Prefix("e/");
public static final Prefix PREFIX_ADDRESS = new Prefix("a/");
+ public static final Prefix PREFIX_ROLE = new Prefix("r/");
public static final Prefix PREFIX_TAG = new Prefix("t/");
-
+ public static final Prefix PREFIX_DATE = new Prefix("id/");
+ public static final Prefix PREFIX_NOTE = new Prefix("i/");
}
diff --git a/src/main/java/hirehive/address/logic/parser/DeleteCommandParser.java b/src/main/java/hirehive/address/logic/parser/DeleteCommandParser.java
new file mode 100644
index 00000000000..16e5381e0e5
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/parser/DeleteCommandParser.java
@@ -0,0 +1,52 @@
+package hirehive.address.logic.parser;
+
+import static hirehive.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static java.util.Objects.isNull;
+import static java.util.Objects.requireNonNull;
+
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.logic.commands.DeleteCommand;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+
+/**
+ * Parses input arguments and creates a new DeleteCommand object
+ */
+public class DeleteCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the DeleteCommand
+ * and returns a DeleteCommand object for execution.
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public DeleteCommand parse(String args) throws ParseException {
+ requireNonNull(args);
+ ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME);
+ argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME);
+
+ boolean hasIndex = !argMultimap.getPreamble().isBlank();
+ boolean hasName = argMultimap.getValue(PREFIX_NAME).isPresent();
+
+ if (hasIndex && hasName) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE));
+ }
+
+ if (argMultimap.getValue(PREFIX_NAME).isPresent()) {
+ String nameKeywords = argMultimap.getValue(PREFIX_NAME).get().trim();
+ if (nameKeywords.isBlank()) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE));
+ }
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(nameKeywords));
+ return new DeleteCommand(nameQuery);
+ }
+
+ try {
+ Index index = ParserUtil.parseIndex(argMultimap.getPreamble());
+ return new DeleteCommand(index);
+ } catch (ParseException e) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE));
+ }
+ }
+}
diff --git a/src/main/java/hirehive/address/logic/parser/DisplayNoteCommandParser.java b/src/main/java/hirehive/address/logic/parser/DisplayNoteCommandParser.java
new file mode 100644
index 00000000000..4fdc96908b4
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/parser/DisplayNoteCommandParser.java
@@ -0,0 +1,38 @@
+package hirehive.address.logic.parser;
+
+import static hirehive.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static java.util.Objects.requireNonNull;
+
+import hirehive.address.logic.commands.DisplayNoteCommand;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+
+/**
+ * Parses input argument and creates a new DisplayNoteCommand object.
+ */
+public class DisplayNoteCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} argument in the context of the DisplayNoteCommand
+ * and returns a DisplayNoteCommand object for execution.
+ * @throws ParseException if the user input does not conform the expected format.
+ */
+ public DisplayNoteCommand parse(String args) throws ParseException {
+ requireNonNull(args);
+ ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME);
+
+ if (argMultimap.getValue(PREFIX_NAME).orElse("").trim().isEmpty()) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DisplayNoteCommand.MESSAGE_USAGE));
+ }
+
+ argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME);
+
+ String nameKeyword = argMultimap.getValue(PREFIX_NAME).get();
+ //NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(nameKeyword));
+
+ return new DisplayNoteCommand(nameKeyword);
+ }
+
+}
diff --git a/src/main/java/hirehive/address/logic/parser/EditCommandParser.java b/src/main/java/hirehive/address/logic/parser/EditCommandParser.java
new file mode 100644
index 00000000000..040a591ddcb
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/parser/EditCommandParser.java
@@ -0,0 +1,86 @@
+package hirehive.address.logic.parser;
+
+import static hirehive.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_DATE;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_EMAIL;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NOTE;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_PHONE;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_ROLE;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_TAG;
+import static java.util.Objects.requireNonNull;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Optional;
+import java.util.Set;
+
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.logic.commands.EditCommand;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.tag.Tag;
+
+
+/**
+ * Parses input arguments and creates a new EditCommand object
+ */
+public class EditCommandParser 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 EditCommand parse(String args) throws ParseException {
+ requireNonNull(args);
+ ArgumentMultimap argMultimap =
+ ArgumentTokenizer.tokenize(
+ args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_ROLE, PREFIX_TAG,
+ PREFIX_NOTE, PREFIX_DATE);
+
+ Index index;
+
+ if (argMultimap.getPreamble().trim().isEmpty()) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE));
+ } else {
+ index = ParserUtil.parseIndex(argMultimap.getPreamble());
+ }
+
+ argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS,
+ PREFIX_TAG, PREFIX_NOTE,
+ PREFIX_DATE);
+
+ EditCommand.EditPersonDescriptor editPersonDescriptor = new EditCommand.EditPersonDescriptor();
+
+ if (argMultimap.getValue(PREFIX_NAME).isPresent()) {
+ editPersonDescriptor.setName(ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get()));
+ }
+ if (argMultimap.getValue(PREFIX_PHONE).isPresent()) {
+ editPersonDescriptor.setPhone(ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get()));
+ }
+ if (argMultimap.getValue(PREFIX_EMAIL).isPresent()) {
+ editPersonDescriptor.setEmail(ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get()));
+ }
+ if (argMultimap.getValue(PREFIX_ADDRESS).isPresent()) {
+ editPersonDescriptor.setAddress(ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get()));
+ }
+ if (argMultimap.getValue(PREFIX_ROLE).isPresent()) {
+ editPersonDescriptor.setRole(ParserUtil.parseRole(argMultimap.getValue(PREFIX_ROLE).get()));
+ }
+ if (argMultimap.getValue(PREFIX_TAG).isPresent()) {
+ editPersonDescriptor.setTag(ParserUtil.parseTag(argMultimap.getValue(PREFIX_TAG).get()));
+ }
+ if (argMultimap.getValue(PREFIX_NOTE).isPresent()) {
+ editPersonDescriptor.setNote(ParserUtil.parseNote(argMultimap.getValue(PREFIX_NOTE).get()));
+ }
+ if (argMultimap.getValue(PREFIX_DATE).isPresent()) {
+ editPersonDescriptor.setDate(ParserUtil.parseDate(argMultimap.getValue(PREFIX_DATE).get()));
+ }
+ if (!editPersonDescriptor.isAnyFieldEdited()) {
+ throw new ParseException(EditCommand.MESSAGE_NOT_EDITED);
+ }
+
+ return new EditCommand(index, editPersonDescriptor);
+ }
+}
diff --git a/src/main/java/hirehive/address/logic/parser/FilterCommandParser.java b/src/main/java/hirehive/address/logic/parser/FilterCommandParser.java
new file mode 100644
index 00000000000..e0d4fddd634
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/parser/FilterCommandParser.java
@@ -0,0 +1,34 @@
+package hirehive.address.logic.parser;
+
+import static hirehive.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_TAG;
+import static java.util.Objects.requireNonNull;
+
+import hirehive.address.logic.commands.FilterCommand;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.PersonContainsTagPredicate;
+import hirehive.address.model.tag.Tag;
+
+/**
+ * Parses input arguments and creates a new FilterCommand object
+ */
+public class FilterCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the FilterCommand
+ * and returns a FilterCommand object for execution.
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public FilterCommand parse(String args) throws ParseException {
+ requireNonNull(args);
+ ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_TAG);
+ Tag tag;
+ argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_TAG);
+ if (argMultimap.getValue(PREFIX_TAG).isEmpty()) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, FilterCommand.MESSAGE_USAGE));
+ }
+ tag = ParserUtil.parseTag(argMultimap.getValue(PREFIX_TAG).get());
+ return new FilterCommand(new PersonContainsTagPredicate(tag));
+ }
+}
diff --git a/src/main/java/hirehive/address/logic/parser/FilterOutCommandParser.java b/src/main/java/hirehive/address/logic/parser/FilterOutCommandParser.java
new file mode 100644
index 00000000000..1fb5e6d8649
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/parser/FilterOutCommandParser.java
@@ -0,0 +1,39 @@
+package hirehive.address.logic.parser;
+
+import static hirehive.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_TAG;
+import static java.util.Objects.requireNonNull;
+
+import hirehive.address.logic.commands.FilterOutCommand;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.PersonDoesNotContainTagPredicate;
+import hirehive.address.model.tag.Tag;
+
+/**
+ * Parses input arguments and creates a new FilterOutCommand object
+ */
+public class FilterOutCommandParser implements Parser {
+ /**
+ * Parses the given {@code String} of arguments in the context of the FilterOutCommand
+ * and returns a FilterOutCommand object for execution.
+ * @param args the user input
+ * @return a new FilterOutCommand
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public FilterOutCommand parse(String args) throws ParseException {
+ requireNonNull(args);
+ ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_TAG);
+
+ Tag tag;
+ argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_TAG);
+ if (argMultimap.getValue(PREFIX_NAME).map(String::trim).filter(String::isEmpty).isPresent()) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, FilterOutCommand.MESSAGE_USAGE));
+ }
+
+ tag = ParserUtil.parseTag(argMultimap.getValue(PREFIX_TAG).orElseThrow(() ->
+ new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, FilterOutCommand.MESSAGE_USAGE))));
+ return new FilterOutCommand(new PersonDoesNotContainTagPredicate(tag));
+ }
+}
diff --git a/src/main/java/seedu/address/logic/parser/FindCommandParser.java b/src/main/java/hirehive/address/logic/parser/FindCommandParser.java
similarity index 56%
rename from src/main/java/seedu/address/logic/parser/FindCommandParser.java
rename to src/main/java/hirehive/address/logic/parser/FindCommandParser.java
index 2867bde857b..cf36208939b 100644
--- a/src/main/java/seedu/address/logic/parser/FindCommandParser.java
+++ b/src/main/java/hirehive/address/logic/parser/FindCommandParser.java
@@ -1,12 +1,9 @@
-package seedu.address.logic.parser;
+package hirehive.address.logic.parser;
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-
-import java.util.Arrays;
-
-import seedu.address.logic.commands.FindCommand;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.FindCommand;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
/**
* Parses input arguments and creates a new FindCommand object
@@ -22,12 +19,10 @@ public FindCommand parse(String args) throws ParseException {
String trimmedArgs = args.trim();
if (trimmedArgs.isEmpty()) {
throw new ParseException(
- String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE));
+ String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE));
}
- String[] nameKeywords = trimmedArgs.split("\\s+");
-
- return new FindCommand(new NameContainsKeywordsPredicate(Arrays.asList(nameKeywords)));
+ return new FindCommand(new NameContainsKeywordsPredicate(trimmedArgs));
}
}
diff --git a/src/main/java/hirehive/address/logic/parser/NewNoteCommandParser.java b/src/main/java/hirehive/address/logic/parser/NewNoteCommandParser.java
new file mode 100644
index 00000000000..5a24e6da000
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/parser/NewNoteCommandParser.java
@@ -0,0 +1,43 @@
+package hirehive.address.logic.parser;
+
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NOTE;
+import static java.util.Objects.requireNonNull;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.EditCommand.EditPersonDescriptor;
+import hirehive.address.logic.commands.NewNoteCommand;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+
+/**
+ * Parses input arguments and creates a new NewNoteCommand object
+ */
+public class NewNoteCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the NewNoteCommand
+ * and returns a NewNoteCommand object for execution.
+ * @throws ParseException if the user input does not conform to the expected format
+ */
+ public NewNoteCommand parse(String args) throws ParseException {
+ requireNonNull(args);
+ ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_NOTE);
+ if (argMultimap.getValue(PREFIX_NAME).orElse("").trim().isEmpty()
+ || argMultimap.getValue(PREFIX_NOTE).isEmpty()) {
+ throw new ParseException(String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT,
+ NewNoteCommand.MESSAGE_USAGE));
+ }
+ argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_NOTE);
+
+ String name = argMultimap.getValue(PREFIX_NAME).get();
+ //NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(name));
+
+ EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor();
+ editPersonDescriptor.setNote(ParserUtil.parseNote(argMultimap.getValue(PREFIX_NOTE).get().trim()));
+
+ return new NewNoteCommand(name, editPersonDescriptor);
+ }
+
+}
diff --git a/src/main/java/seedu/address/logic/parser/Parser.java b/src/main/java/hirehive/address/logic/parser/Parser.java
similarity index 71%
rename from src/main/java/seedu/address/logic/parser/Parser.java
rename to src/main/java/hirehive/address/logic/parser/Parser.java
index d6551ad8e3f..e084684bb48 100644
--- a/src/main/java/seedu/address/logic/parser/Parser.java
+++ b/src/main/java/hirehive/address/logic/parser/Parser.java
@@ -1,7 +1,7 @@
-package seedu.address.logic.parser;
+package hirehive.address.logic.parser;
-import seedu.address.logic.commands.Command;
-import seedu.address.logic.parser.exceptions.ParseException;
+import hirehive.address.logic.commands.Command;
+import hirehive.address.logic.parser.exceptions.ParseException;
/**
* Represents a Parser that is able to parse user input into a {@code Command} of type {@code T}.
diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/hirehive/address/logic/parser/ParserUtil.java
similarity index 50%
rename from src/main/java/seedu/address/logic/parser/ParserUtil.java
rename to src/main/java/hirehive/address/logic/parser/ParserUtil.java
index b117acb9c55..357d4edbe8e 100644
--- a/src/main/java/seedu/address/logic/parser/ParserUtil.java
+++ b/src/main/java/hirehive/address/logic/parser/ParserUtil.java
@@ -1,4 +1,4 @@
-package seedu.address.logic.parser;
+package hirehive.address.logic.parser;
import static java.util.Objects.requireNonNull;
@@ -6,21 +6,27 @@
import java.util.HashSet;
import java.util.Set;
-import seedu.address.commons.core.index.Index;
-import seedu.address.commons.util.StringUtil;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.commons.util.StringUtil;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.Address;
+import hirehive.address.model.person.Email;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.Name;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Phone;
+import hirehive.address.model.person.Role;
+import hirehive.address.model.tag.Tag;
/**
* Contains utility methods used for parsing strings in the various *Parser classes.
*/
public class ParserUtil {
- public static final String MESSAGE_INVALID_INDEX = "Index is not a non-zero unsigned integer.";
+ public static final String MESSAGE_INVALID_INDEX = "Input is not a non-zero unsigned integer.";
+ public static final String MESSAGE_INVALID_DAYS = "Input is not a positive integer.";
+ public static final String MESSAGE_OUT_OF_RANGE = "Number is out of integer range!\n"
+ + "(must be within -2^31 to 2^31 inclusive)";
/**
* Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading and trailing whitespaces will be
@@ -29,12 +35,29 @@ public class ParserUtil {
*/
public static Index parseIndex(String oneBasedIndex) throws ParseException {
String trimmedIndex = oneBasedIndex.trim();
- if (!StringUtil.isNonZeroUnsignedInteger(trimmedIndex)) {
+ if (!StringUtil.isValidStringOrInteger(trimmedIndex)) {
+ throw new ParseException(MESSAGE_OUT_OF_RANGE);
+ } else if (!StringUtil.isNonZeroUnsignedInteger(trimmedIndex)) {
throw new ParseException(MESSAGE_INVALID_INDEX);
}
return Index.fromOneBased(Integer.parseInt(trimmedIndex));
}
+ /**
+ * Parses {@code days} into an {@code int} and returns it. Leading and trailing whitespaces will be
+ * trimmed.
+ * @throws ParseException if the specified days are invalid (not positive integer)
+ */
+ public static int parseDays(String days) throws ParseException {
+ String trimmedDays = days.trim();
+ if (!StringUtil.isValidStringOrInteger(trimmedDays)) {
+ throw new ParseException(MESSAGE_OUT_OF_RANGE);
+ } else if (!StringUtil.isPositiveInteger(trimmedDays)) {
+ throw new ParseException(MESSAGE_INVALID_DAYS);
+ }
+ return Integer.parseInt(trimmedDays);
+ }
+
/**
* Parses a {@code String name} into a {@code Name}.
* Leading and trailing whitespaces will be trimmed.
@@ -95,6 +118,21 @@ public static Email parseEmail(String email) throws ParseException {
return new Email(trimmedEmail);
}
+ /**
+ * Parses a {@code String role} into an {@code Role}.
+ * Leading and trailing whitespaces will be trimmed.
+ *
+ * @throws ParseException if the given {@code role} is invalid.
+ */
+ public static Role parseRole(String role) throws ParseException {
+ requireNonNull(role);
+ String trimmedRole = role.trim();
+ if (!Role.isValidRole(trimmedRole)) {
+ throw new ParseException(Role.MESSAGE_CONSTRAINTS);
+ }
+ return new Role(trimmedRole);
+ }
+
/**
* Parses a {@code String tag} into a {@code Tag}.
* Leading and trailing whitespaces will be trimmed.
@@ -103,11 +141,21 @@ public static Email parseEmail(String email) throws ParseException {
*/
public static Tag parseTag(String tag) throws ParseException {
requireNonNull(tag);
- String trimmedTag = tag.trim();
- if (!Tag.isValidTagName(trimmedTag)) {
+ String adjustedTag = tag.trim().toLowerCase();
+ switch (adjustedTag) {
+ case "applicant":
+ return Tag.APPLICANT;
+ case "candidate":
+ return Tag.CANDIDATE;
+ case "interviewee":
+ return Tag.INTERVIEWEE;
+ case "offered":
+ return Tag.OFFERED;
+ case "rejected":
+ return Tag.REJECTED;
+ default:
throw new ParseException(Tag.MESSAGE_CONSTRAINTS);
}
- return new Tag(trimmedTag);
}
/**
@@ -121,4 +169,34 @@ public static Set parseTags(Collection tags) throws ParseException
}
return tagSet;
}
+
+ /**
+ * Parses a {@code String note} into a {@code Note}.
+ * Leading and trailing whitespaces will be trimmed.
+ *
+ * @throws ParseException if the given {@code note} is invalid.
+ */
+ public static Note parseNote(String note) throws ParseException {
+ requireNonNull(note);
+ String trimmedNote = note.trim();
+ if (!Note.isValidNote(trimmedNote)) {
+ throw new ParseException(Note.MESSAGE_CONSTRAINTS);
+ }
+ return new Note(trimmedNote);
+ }
+
+ /**
+ * Parses a {@code String date} into a {@code InterviewDate}.
+ * Leading and trailing whitespaces will be trimmed.
+ *
+ * @throws ParseException if the given {@code date} is invalid.
+ */
+ public static InterviewDate parseDate(String date) throws ParseException {
+ requireNonNull(date);
+ String trimmedDate = date.trim();
+ if (!InterviewDate.isValidDate(trimmedDate)) {
+ throw new ParseException(InterviewDate.MESSAGE_CONSTRAINTS);
+ }
+ return new InterviewDate(trimmedDate);
+ }
}
diff --git a/src/main/java/seedu/address/logic/parser/Prefix.java b/src/main/java/hirehive/address/logic/parser/Prefix.java
similarity index 95%
rename from src/main/java/seedu/address/logic/parser/Prefix.java
rename to src/main/java/hirehive/address/logic/parser/Prefix.java
index 348b7686c8a..6d28f904b5b 100644
--- a/src/main/java/seedu/address/logic/parser/Prefix.java
+++ b/src/main/java/hirehive/address/logic/parser/Prefix.java
@@ -1,4 +1,4 @@
-package seedu.address.logic.parser;
+package hirehive.address.logic.parser;
/**
* A prefix that marks the beginning of an argument in an arguments string.
diff --git a/src/main/java/hirehive/address/logic/parser/ReminderCommandParser.java b/src/main/java/hirehive/address/logic/parser/ReminderCommandParser.java
new file mode 100644
index 00000000000..82e49a5bdd2
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/parser/ReminderCommandParser.java
@@ -0,0 +1,37 @@
+package hirehive.address.logic.parser;
+
+import static hirehive.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_TAG;
+import static java.util.Objects.requireNonNull;
+
+import hirehive.address.logic.commands.EditCommand;
+import hirehive.address.logic.commands.FilterCommand;
+import hirehive.address.logic.commands.ReminderCommand;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.PersonContainsTagPredicate;
+import hirehive.address.model.person.UpcomingInterviewPredicate;
+import hirehive.address.model.tag.Tag;
+
+/**
+ * Parses input arguments and creates a new ReminderCommand object
+ */
+public class ReminderCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the ReminderCommand
+ * and returns a ReminderCommand object for execution.
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public ReminderCommand parse(String args) throws ParseException {
+ requireNonNull(args);
+ ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args);
+ int days;
+
+ if (argMultimap.getPreamble().trim().isEmpty()) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, ReminderCommand.MESSAGE_USAGE));
+ } else {
+ days = ParserUtil.parseDays(argMultimap.getPreamble());
+ }
+ return new ReminderCommand(new UpcomingInterviewPredicate(days));
+ }
+}
diff --git a/src/main/java/hirehive/address/logic/parser/ScheduleCommandParser.java b/src/main/java/hirehive/address/logic/parser/ScheduleCommandParser.java
new file mode 100644
index 00000000000..5792532a710
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/parser/ScheduleCommandParser.java
@@ -0,0 +1,70 @@
+package hirehive.address.logic.parser;
+
+import static hirehive.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_DATE;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static java.util.Objects.requireNonNull;
+
+import java.time.LocalDate;
+
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.logic.commands.EditCommand;
+import hirehive.address.logic.commands.ScheduleCommand;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+
+/**
+ * Parses input arguments and creates a new DateCommand object
+ */
+public class ScheduleCommandParser implements Parser {
+ public static final String MESSAGE_DATE_OUT_OF_BOUNDS = "The given date has already passed."
+ + "Please provide a valid date.";
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the DateCommand
+ * and returns a DateCommand object for execution.
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public ScheduleCommand parse(String args) throws ParseException {
+ requireNonNull(args);
+ ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_DATE);
+ NameQuery nameQuery = null;
+ Index index = null;
+ InterviewDate date = null;
+
+ if (argMultimap.getValue(PREFIX_NAME).orElse("").trim().isEmpty()
+ && argMultimap.getPreamble().trim().isEmpty()) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, ScheduleCommand.MESSAGE_USAGE));
+ }
+ if (argMultimap.getPreamble().trim().isEmpty()) {
+ String name = argMultimap.getValue(PREFIX_NAME).get();
+ nameQuery = new NameQuery(new NameContainsKeywordsPredicate(name));
+ } else {
+ index = ParserUtil.parseIndex(argMultimap.getPreamble().trim());
+ }
+ if (!argMultimap.getValue(PREFIX_DATE).orElse("").trim().isEmpty()) {
+ date = ParserUtil.parseDate(argMultimap.getValue(PREFIX_DATE).get());
+ if (date.getValue().get().isBefore(LocalDate.now())) {
+ throw new ParseException(MESSAGE_DATE_OUT_OF_BOUNDS);
+ }
+ }
+ if (date == null) {
+ if (index == null) {
+ return new ScheduleCommand(nameQuery);
+ } else {
+ return new ScheduleCommand(index);
+ }
+ } else {
+ EditCommand.EditPersonDescriptor editPersonDescriptor = new EditCommand.EditPersonDescriptor();
+ editPersonDescriptor.setDate(date);
+ if (index == null) {
+ return new ScheduleCommand(nameQuery, editPersonDescriptor);
+ } else {
+ return new ScheduleCommand(index, editPersonDescriptor);
+ }
+ }
+ }
+}
diff --git a/src/main/java/hirehive/address/logic/parser/TagCommandParser.java b/src/main/java/hirehive/address/logic/parser/TagCommandParser.java
new file mode 100644
index 00000000000..32650f6cc02
--- /dev/null
+++ b/src/main/java/hirehive/address/logic/parser/TagCommandParser.java
@@ -0,0 +1,79 @@
+package hirehive.address.logic.parser;
+
+import static hirehive.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_TAG;
+import static java.lang.Math.abs;
+import static java.util.Objects.requireNonNull;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Optional;
+import java.util.Set;
+
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.logic.commands.EditCommand.EditPersonDescriptor;
+import hirehive.address.logic.commands.TagCommand;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.model.tag.Tag;
+
+/**
+ * Parses input arguments and creates a new TagCommand object
+ */
+public class TagCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the TagCommand
+ * and returns an TagCommand object for execution.
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public TagCommand parse(String args) throws ParseException {
+ requireNonNull(args);
+ ArgumentMultimap argMultimap =
+ ArgumentTokenizer.tokenize(
+ args, PREFIX_NAME, PREFIX_TAG);
+
+ EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor();
+
+ if (argMultimap.getValue(PREFIX_TAG).isEmpty()) {
+ if (argMultimap.getValue(PREFIX_NAME).isEmpty()) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, TagCommand.MESSAGE_USAGE));
+ }
+ String nameKeywords = argMultimap.getValue(PREFIX_NAME).get();
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(nameKeywords));
+ try {
+ int offset = Integer.parseInt(argMultimap.getPreamble());
+ if (abs(offset) > 4) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, TagCommand.MESSAGE_TAG_INVALID_OFFSET)
+ );
+ }
+ return new TagCommand(nameQuery, offset);
+ } catch (NumberFormatException e) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, TagCommand.MESSAGE_USAGE));
+ }
+ }
+
+ editPersonDescriptor.setTag(ParserUtil.parseTag(argMultimap.getValue(PREFIX_TAG).get()));
+
+ if (argMultimap.getValue(PREFIX_NAME).isEmpty()) {
+ Index index;
+ try {
+ index = ParserUtil.parseIndex(argMultimap.getPreamble());
+ return new TagCommand(index, editPersonDescriptor);
+ } catch (ParseException e) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, TagCommand.MESSAGE_USAGE));
+ }
+ }
+
+ String nameKeywords = argMultimap.getValue(PREFIX_NAME).get();
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(nameKeywords));
+
+ return new TagCommand(nameQuery, editPersonDescriptor);
+ }
+}
diff --git a/src/main/java/seedu/address/logic/parser/exceptions/ParseException.java b/src/main/java/hirehive/address/logic/parser/exceptions/ParseException.java
similarity index 72%
rename from src/main/java/seedu/address/logic/parser/exceptions/ParseException.java
rename to src/main/java/hirehive/address/logic/parser/exceptions/ParseException.java
index 158a1a54c1c..b8bf2d5569b 100644
--- a/src/main/java/seedu/address/logic/parser/exceptions/ParseException.java
+++ b/src/main/java/hirehive/address/logic/parser/exceptions/ParseException.java
@@ -1,6 +1,6 @@
-package seedu.address.logic.parser.exceptions;
+package hirehive.address.logic.parser.exceptions;
-import seedu.address.commons.exceptions.IllegalValueException;
+import hirehive.address.commons.exceptions.IllegalValueException;
/**
* Represents a parse error encountered by a parser.
diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/hirehive/address/model/AddressBook.java
similarity index 94%
rename from src/main/java/seedu/address/model/AddressBook.java
rename to src/main/java/hirehive/address/model/AddressBook.java
index 73397161e84..6fcd97b988f 100644
--- a/src/main/java/seedu/address/model/AddressBook.java
+++ b/src/main/java/hirehive/address/model/AddressBook.java
@@ -1,13 +1,13 @@
-package seedu.address.model;
+package hirehive.address.model;
import static java.util.Objects.requireNonNull;
import java.util.List;
+import hirehive.address.commons.util.ToStringBuilder;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.person.UniquePersonList;
import javafx.collections.ObservableList;
-import seedu.address.commons.util.ToStringBuilder;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.UniquePersonList;
/**
* Wraps all data at the address-book level
diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/hirehive/address/model/Model.java
similarity index 73%
rename from src/main/java/seedu/address/model/Model.java
rename to src/main/java/hirehive/address/model/Model.java
index d54df471c1f..9a995d8f07d 100644
--- a/src/main/java/seedu/address/model/Model.java
+++ b/src/main/java/hirehive/address/model/Model.java
@@ -1,11 +1,14 @@
-package seedu.address.model;
+package hirehive.address.model;
import java.nio.file.Path;
+import java.time.LocalDate;
import java.util.function.Predicate;
+import hirehive.address.commons.core.GuiSettings;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
import javafx.collections.ObservableList;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.model.person.Person;
/**
* The API of the Model component.
@@ -84,4 +87,33 @@ public interface Model {
* @throws NullPointerException if {@code predicate} is null.
*/
void updateFilteredPersonList(Predicate predicate);
+
+ void unfilterPersonList();
+
+ /**
+ * Sorts the filtered person list by their interview date.
+ */
+ void sortPersons();
+
+ /**
+ * Resets the sorted list when other commands are typed.
+ */
+ void resetSorting();
+
+ /**
+ * Updates the notes of the person.
+ */
+ void updatePersonNote(Person person);
+
+ /**
+ * Returns the notes of the person.
+ */
+ Note getPersonNote();
+
+ int getListSize();
+
+ /**
+ * Returns the next available date for an interview from the current date.
+ */
+ InterviewDate getAvailableDate();
}
diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/hirehive/address/model/ModelManager.java
similarity index 54%
rename from src/main/java/seedu/address/model/ModelManager.java
rename to src/main/java/hirehive/address/model/ModelManager.java
index 57bc563fde6..38753ad1c84 100644
--- a/src/main/java/seedu/address/model/ModelManager.java
+++ b/src/main/java/hirehive/address/model/ModelManager.java
@@ -1,17 +1,26 @@
-package seedu.address.model;
+package hirehive.address.model;
import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
import java.nio.file.Path;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.ResolverStyle;
+import java.util.Comparator;
+import java.util.List;
import java.util.function.Predicate;
import java.util.logging.Logger;
-
+import java.util.stream.Stream;
+
+import hirehive.address.commons.core.GuiSettings;
+import hirehive.address.commons.core.LogsCenter;
+import hirehive.address.commons.util.CollectionUtil;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.model.person.Person;
+import javafx.collections.transformation.SortedList;
/**
* Represents the in-memory model of the address book data.
@@ -22,18 +31,25 @@ public class ModelManager implements Model {
private final AddressBook addressBook;
private final UserPrefs userPrefs;
private final FilteredList filteredPersons;
+ private Note personNote;
+ private final SortedList sortedPersons;
+ private boolean isSorted = false;
+
+ private Predicate currFilter = PREDICATE_SHOW_ALL_PERSONS;
/**
* Initializes a ModelManager with the given addressBook and userPrefs.
*/
public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyUserPrefs userPrefs) {
- requireAllNonNull(addressBook, userPrefs);
+ CollectionUtil.requireAllNonNull(addressBook, userPrefs);
logger.fine("Initializing with address book: " + addressBook + " and user prefs " + userPrefs);
this.addressBook = new AddressBook(addressBook);
this.userPrefs = new UserPrefs(userPrefs);
filteredPersons = new FilteredList<>(this.addressBook.getPersonList());
+ personNote = new Note(Note.DEFAULT_NOTE);
+ this.sortedPersons = new SortedList<>(filteredPersons);
}
public ModelManager() {
@@ -101,12 +117,12 @@ public void deletePerson(Person target) {
@Override
public void addPerson(Person person) {
addressBook.addPerson(person);
- updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
+ unfilterPersonList();
}
@Override
public void setPerson(Person target, Person editedPerson) {
- requireAllNonNull(target, editedPerson);
+ CollectionUtil.requireAllNonNull(target, editedPerson);
addressBook.setPerson(target, editedPerson);
}
@@ -119,13 +135,81 @@ public void setPerson(Person target, Person editedPerson) {
*/
@Override
public ObservableList getFilteredPersonList() {
- return filteredPersons;
+ return sortedPersons;
}
@Override
public void updateFilteredPersonList(Predicate predicate) {
requireNonNull(predicate);
- filteredPersons.setPredicate(predicate);
+ currFilter = currFilter.and(predicate);
+ filteredPersons.setPredicate(currFilter);
+ resetSorting();
+ }
+
+ @Override
+ public void unfilterPersonList() {
+ currFilter = PREDICATE_SHOW_ALL_PERSONS;
+ filteredPersons.setPredicate(PREDICATE_SHOW_ALL_PERSONS);
+ resetSorting();
+ }
+
+ @Override
+ public void sortPersons() {
+ Comparator comparator = Comparator.comparing(
+ person -> person.getDate().getValue().orElse(LocalDate.MAX)
+ );
+ sortedPersons.setComparator(comparator);
+ isSorted = true;
+ }
+
+ @Override
+ public void resetSorting() {
+ sortedPersons.setComparator(null);
+ isSorted = false;
+ }
+
+
+ @Override
+ public void updatePersonNote(Person person) {
+ personNote = person.getNote();
+ }
+
+ @Override
+ public Note getPersonNote() {
+ return personNote;
+ }
+
+ @Override
+ public int getListSize() {
+ return filteredPersons.size();
+ }
+
+ /**
+ * Returns the next available date for an interview starting from the next day.
+ * @return An {@code InterviewDate} object
+ */
+ @Override
+ public InterviewDate getAvailableDate() {
+ List sortedAllDates = this.addressBook.getPersonList().stream()
+ .map(person -> person.getDate().getValue().orElse(LocalDate.MAX))
+ .sorted(LocalDate::compareTo).toList();
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu")
+ .withResolverStyle(ResolverStyle.STRICT);
+ LocalDate iterationDate = LocalDate.now().plusDays(1);
+ boolean bContinue = true;
+ int i = 0;
+ while (i < sortedAllDates.size() && sortedAllDates.get(i) != LocalDate.MAX && bContinue) {
+ LocalDate currDate = sortedAllDates.get(i);
+ if (currDate.isBefore(iterationDate)) {
+ i++;
+ } else if (currDate.isAfter(iterationDate)) {
+ bContinue = false;
+ } else {
+ iterationDate = iterationDate.plusDays(1);
+ i++;
+ }
+ }
+ return new InterviewDate(iterationDate.format(formatter));
}
@Override
diff --git a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java b/src/main/java/hirehive/address/model/ReadOnlyAddressBook.java
similarity index 80%
rename from src/main/java/seedu/address/model/ReadOnlyAddressBook.java
rename to src/main/java/hirehive/address/model/ReadOnlyAddressBook.java
index 6ddc2cd9a29..6404a7728f6 100644
--- a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java
+++ b/src/main/java/hirehive/address/model/ReadOnlyAddressBook.java
@@ -1,7 +1,7 @@
-package seedu.address.model;
+package hirehive.address.model;
+import hirehive.address.model.person.Person;
import javafx.collections.ObservableList;
-import seedu.address.model.person.Person;
/**
* Unmodifiable view of an address book
diff --git a/src/main/java/seedu/address/model/ReadOnlyUserPrefs.java b/src/main/java/hirehive/address/model/ReadOnlyUserPrefs.java
similarity index 69%
rename from src/main/java/seedu/address/model/ReadOnlyUserPrefs.java
rename to src/main/java/hirehive/address/model/ReadOnlyUserPrefs.java
index befd58a4c73..583737cf8eb 100644
--- a/src/main/java/seedu/address/model/ReadOnlyUserPrefs.java
+++ b/src/main/java/hirehive/address/model/ReadOnlyUserPrefs.java
@@ -1,8 +1,8 @@
-package seedu.address.model;
+package hirehive.address.model;
import java.nio.file.Path;
-import seedu.address.commons.core.GuiSettings;
+import hirehive.address.commons.core.GuiSettings;
/**
* Unmodifiable view of user prefs.
diff --git a/src/main/java/seedu/address/model/UserPrefs.java b/src/main/java/hirehive/address/model/UserPrefs.java
similarity index 96%
rename from src/main/java/seedu/address/model/UserPrefs.java
rename to src/main/java/hirehive/address/model/UserPrefs.java
index 6be655fb4c7..1204e610030 100644
--- a/src/main/java/seedu/address/model/UserPrefs.java
+++ b/src/main/java/hirehive/address/model/UserPrefs.java
@@ -1,4 +1,4 @@
-package seedu.address.model;
+package hirehive.address.model;
import static java.util.Objects.requireNonNull;
@@ -6,7 +6,7 @@
import java.nio.file.Paths;
import java.util.Objects;
-import seedu.address.commons.core.GuiSettings;
+import hirehive.address.commons.core.GuiSettings;
/**
* Represents User's preferences.
diff --git a/src/main/java/seedu/address/model/person/Address.java b/src/main/java/hirehive/address/model/person/Address.java
similarity index 89%
rename from src/main/java/seedu/address/model/person/Address.java
rename to src/main/java/hirehive/address/model/person/Address.java
index 469a2cc9a1e..ec973db7cb6 100644
--- a/src/main/java/seedu/address/model/person/Address.java
+++ b/src/main/java/hirehive/address/model/person/Address.java
@@ -1,7 +1,8 @@
-package seedu.address.model.person;
+package hirehive.address.model.person;
import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.AppUtil.checkArgument;
+
+import hirehive.address.commons.util.AppUtil;
/**
* Represents a Person's address in the address book.
@@ -26,7 +27,7 @@ public class Address {
*/
public Address(String address) {
requireNonNull(address);
- checkArgument(isValidAddress(address), MESSAGE_CONSTRAINTS);
+ AppUtil.checkArgument(isValidAddress(address), MESSAGE_CONSTRAINTS);
value = address;
}
diff --git a/src/main/java/seedu/address/model/person/Email.java b/src/main/java/hirehive/address/model/person/Email.java
similarity index 92%
rename from src/main/java/seedu/address/model/person/Email.java
rename to src/main/java/hirehive/address/model/person/Email.java
index c62e512bc29..2968c371968 100644
--- a/src/main/java/seedu/address/model/person/Email.java
+++ b/src/main/java/hirehive/address/model/person/Email.java
@@ -1,7 +1,9 @@
-package seedu.address.model.person;
+package hirehive.address.model.person;
import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.AppUtil.checkArgument;
+
+import hirehive.address.commons.util.AppUtil;
+
/**
* Represents a Person's email in the address book.
@@ -16,7 +18,7 @@ public class Email {
+ "the parentheses, (" + SPECIAL_CHARACTERS + "). The local-part may not start or end with any special "
+ "characters.\n"
+ "2. This is followed by a '@' and then a domain name. The domain name is made up of domain labels "
- + "separated by periods.\n"
+ + "that may be separated by periods, if any.\n"
+ "The domain name must:\n"
+ " - end with a domain label at least 2 characters long\n"
+ " - have each domain label start and end with alphanumeric characters\n"
@@ -40,7 +42,7 @@ public class Email {
*/
public Email(String email) {
requireNonNull(email);
- checkArgument(isValidEmail(email), MESSAGE_CONSTRAINTS);
+ AppUtil.checkArgument(isValidEmail(email), MESSAGE_CONSTRAINTS);
value = email;
}
diff --git a/src/main/java/hirehive/address/model/person/InterviewDate.java b/src/main/java/hirehive/address/model/person/InterviewDate.java
new file mode 100644
index 00000000000..bc3d43a57fd
--- /dev/null
+++ b/src/main/java/hirehive/address/model/person/InterviewDate.java
@@ -0,0 +1,91 @@
+package hirehive.address.model.person;
+
+import static java.util.Objects.requireNonNull;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.time.format.ResolverStyle;
+import java.util.Optional;
+
+import hirehive.address.commons.util.AppUtil;
+
+/**
+ * Represents a Person's interview date in the address book
+ * Can be empty. Represented in the string format of DD/MM/YYYY
+ * Guarantees: immutable; is valid as declared in {@link #isValidDate(String)}
+ */
+public class InterviewDate {
+ public static final String MESSAGE_CONSTRAINTS = "Please provide a valid date in the DD/MM/YYYY format";
+ public static final String DEFAULT_DATE = "01/01/2025";
+
+ public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/uuuu")
+ .withResolverStyle(ResolverStyle.STRICT);
+
+ public final Optional value;
+
+ public InterviewDate() {
+ value = Optional.empty();
+ }
+
+ /**
+ * Constructor for new {@link InterviewDate} objects with initialized dates
+ * @param date Date value
+ */
+ public InterviewDate(String date) {
+ requireNonNull(date);
+ AppUtil.checkArgument(isValidDate(date), MESSAGE_CONSTRAINTS);
+ if (!date.isEmpty()) {
+ value = Optional.of(LocalDate.parse(date, DATE_TIME_FORMATTER));
+ } else {
+ value = Optional.empty();
+ }
+ }
+
+ /**
+ * Returns true if a given string is a valid date.
+ */
+ public static boolean isValidDate(String test) {
+ if (test.isEmpty()) {
+ return true;
+ }
+ try {
+ LocalDate.parse(test, DATE_TIME_FORMATTER);
+ return true;
+ } catch (DateTimeParseException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the value of the interview date, or empty if not set.
+ */
+ public Optional getValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return value.map(x -> x.format(DATE_TIME_FORMATTER)).orElse("");
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof InterviewDate)) {
+ return false;
+ }
+
+ InterviewDate otherDate = (InterviewDate) other;
+ return value.equals(otherDate.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+}
diff --git a/src/main/java/seedu/address/model/person/Name.java b/src/main/java/hirehive/address/model/person/Name.java
similarity index 70%
rename from src/main/java/seedu/address/model/person/Name.java
rename to src/main/java/hirehive/address/model/person/Name.java
index 173f15b9b00..0f087e3a0fa 100644
--- a/src/main/java/seedu/address/model/person/Name.java
+++ b/src/main/java/hirehive/address/model/person/Name.java
@@ -1,7 +1,8 @@
-package seedu.address.model.person;
+package hirehive.address.model.person;
import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.AppUtil.checkArgument;
+
+import hirehive.address.commons.util.AppUtil;
/**
* Represents a Person's name in the address book.
@@ -10,13 +11,15 @@
public class Name {
public static final String MESSAGE_CONSTRAINTS =
- "Names should only contain alphanumeric characters and spaces, and it should not be blank";
+ "Names should only contain English letters, spaces, and the following symbols:\n"
+ + " , ( ) / . @ - '\n"
+ + "Names should not be blank or start with a symbol.";
/*
* The first character of the address must not be a whitespace,
* otherwise " " (a blank string) becomes a valid input.
*/
- public static final String VALIDATION_REGEX = "[\\p{Alnum}][\\p{Alnum} ]*";
+ public static final String VALIDATION_REGEX = "[A-Za-z][A-Za-z ,()/.@'-]*";
public final String fullName;
@@ -27,7 +30,7 @@ public class Name {
*/
public Name(String name) {
requireNonNull(name);
- checkArgument(isValidName(name), MESSAGE_CONSTRAINTS);
+ AppUtil.checkArgument(isValidName(name), MESSAGE_CONSTRAINTS);
fullName = name;
}
@@ -56,7 +59,7 @@ public boolean equals(Object other) {
}
Name otherName = (Name) other;
- return fullName.equals(otherName.fullName);
+ return fullName.equalsIgnoreCase(otherName.fullName);
}
@Override
diff --git a/src/main/java/hirehive/address/model/person/NameContainsKeywordsPredicate.java b/src/main/java/hirehive/address/model/person/NameContainsKeywordsPredicate.java
new file mode 100644
index 00000000000..9ac303f278d
--- /dev/null
+++ b/src/main/java/hirehive/address/model/person/NameContainsKeywordsPredicate.java
@@ -0,0 +1,46 @@
+package hirehive.address.model.person;
+
+import hirehive.address.commons.util.StringUtil;
+import hirehive.address.commons.util.ToStringBuilder;
+import hirehive.address.logic.Messages;
+
+/**
+ * Tests that a {@code Person}'s {@code Name} matches any of the keyword given.
+ */
+public class NameContainsKeywordsPredicate implements PersonPredicate {
+ private final String keyword;
+
+ public NameContainsKeywordsPredicate(String keyword) {
+ this.keyword = keyword;
+ }
+
+ @Override
+ public boolean test(Person person) {
+ return StringUtil.containsWordIgnoreCase(person.getName().fullName, keyword);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof NameContainsKeywordsPredicate)) {
+ return false;
+ }
+
+ NameContainsKeywordsPredicate otherNameContainsKeywordsPredicate = (NameContainsKeywordsPredicate) other;
+ return keyword.equals(otherNameContainsKeywordsPredicate.keyword);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).add("keywords", keyword).toString();
+ }
+
+ @Override
+ public String getSuccessString() {
+ return String.format(Messages.MESSAGE_FILTER_OVERVIEW_NAME, keyword);
+ }
+}
diff --git a/src/main/java/hirehive/address/model/person/Note.java b/src/main/java/hirehive/address/model/person/Note.java
new file mode 100644
index 00000000000..7330ba2174e
--- /dev/null
+++ b/src/main/java/hirehive/address/model/person/Note.java
@@ -0,0 +1,67 @@
+package hirehive.address.model.person;
+
+import static java.util.Objects.requireNonNull;
+
+import hirehive.address.commons.util.AppUtil;
+
+/**
+ * Represents a Person's note in the address book.
+ * Guarantees: immutable; is valid as declared in {@link #isValidNote(String)}
+ */
+public class Note {
+
+ public static final String MESSAGE_CONSTRAINTS = "Notes can take any values, but are limited to 500 characters";
+ public static final String DEFAULT_NOTE = "";
+
+ public final String value;
+
+ /**
+ * Constructs an {@code Notes}.
+ *
+ * @param note A valid note.
+ */
+ public Note(String note) {
+ requireNonNull(note);
+ AppUtil.checkArgument(isValidNote(note), MESSAGE_CONSTRAINTS);
+ value = note;
+ }
+
+ /**
+ * Returns true if a given string is a valid note.
+ */
+ public static boolean isValidNote(String test) {
+ return test.length() <= 500;
+ }
+
+ /**
+ * Returns true if the note is empty.
+ */
+ public boolean isEmpty() {
+ return value.isEmpty();
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+
+ @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 value.equals(otherNote.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+}
diff --git a/src/main/java/hirehive/address/model/person/Person.java b/src/main/java/hirehive/address/model/person/Person.java
new file mode 100644
index 00000000000..b114603a587
--- /dev/null
+++ b/src/main/java/hirehive/address/model/person/Person.java
@@ -0,0 +1,172 @@
+package hirehive.address.model.person;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+import hirehive.address.commons.util.CollectionUtil;
+import hirehive.address.commons.util.ToStringBuilder;
+import hirehive.address.model.tag.Tag;
+
+/**
+ * Represents a Person in the address book.
+ * Guarantees: details are present and not null, field values are validated, immutable.
+ */
+public class Person {
+
+ // Identity fields
+ private final Name name;
+ private final Phone phone;
+ private final Email email;
+
+ // Data fields
+ private final Address address;
+ private final Role role;
+ private final Tag tag;
+ private final Note note;
+ private final InterviewDate date;
+
+ /**
+ * Every field must be present.
+ */
+ public Person(Name name, Phone phone, Email email, Address address, Role role, Tag tag, Note note,
+ InterviewDate date) {
+ CollectionUtil.requireAllNonNull(name, phone, email, address, role, tag, note);
+ this.name = name;
+ this.phone = phone;
+ this.email = email;
+ this.address = address;
+ this.role = role;
+ this.tag = tag;
+ this.note = note;
+ this.date = date;
+ }
+
+ /**
+ * Method used to construct a default Person object without a note.
+ */
+ public static Person createDefaultPerson(Name name, Phone phone, Email email, Address address, Role role) {
+ return new Person(name, phone, email, address, role, Tag.getDefaultTag(), new Note(Note.DEFAULT_NOTE),
+ new InterviewDate());
+ }
+
+ /**
+ * Method used to construct a default Person object with a note.
+ */
+ public static Person addDefaultPersonWithNote(Name name, Phone phone, Email email, Address address, Role role,
+ Note note) {
+ return new Person(name, phone, email, address, role, Tag.getDefaultTag(), note,
+ new InterviewDate());
+ }
+
+ public Name getName() {
+ return name;
+ }
+
+ public Phone getPhone() {
+ return phone;
+ }
+
+ public Email getEmail() {
+ return email;
+ }
+
+ public Address getAddress() {
+ return address;
+ }
+
+ public Role getRole() {
+ return role;
+ }
+
+ public Note getNote() {
+ return note;
+ }
+
+ public InterviewDate getDate() {
+ return date;
+ }
+
+ /**
+ * Returns an immutable tag set, which throws {@code UnsupportedOperationException}
+ * if modification is attempted.
+ */
+ public Tag getTag() {
+ return tag;
+ }
+
+ /**
+ * Returns true if both persons have the same name, ignoring case differences
+ * and ignores number of spacing in name.
+ *
+ * @param otherPerson The other person to compare to.
+ * @return true if the names are equivalent after normalization; false otherwise.
+ */
+ public boolean isSamePerson(Person otherPerson) {
+ if (otherPerson == this) {
+ return true;
+ }
+
+ return otherPerson != null
+ && normalizeName(otherPerson.getName()).equalsIgnoreCase(normalizeName(getName()));
+ }
+
+ /**
+ * Normalizes a name by trimming leading/trailing spaces and
+ * replacing multiple consecutive whitespace characters with a single space.
+ *
+ * @param name The name to normalize.
+ * @return The normalized name.
+ */
+ private String normalizeName(Name name) {
+ return name.toString().trim().replaceAll("\\s+", " ");
+ }
+
+ /**
+ * Returns true if both persons have the same identity and data fields.
+ * This defines a stronger notion of equality between two persons.
+ */
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof Person)) {
+ return false;
+ }
+
+ Person otherPerson = (Person) other;
+ return name.equals(otherPerson.name)
+ && phone.equals(otherPerson.phone)
+ && email.equals(otherPerson.email)
+ && address.equals(otherPerson.address)
+ && role.equals(otherPerson.role)
+ && tag.equals(otherPerson.tag)
+ && note.equals(otherPerson.note)
+ && date.equals(otherPerson.date);
+ }
+
+ @Override
+ public int hashCode() {
+ // use this method for custom fields hashing instead of implementing your own
+ return Objects.hash(name, phone, email, address, role, tag, note, date);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("name", name)
+ .add("phone", phone)
+ .add("email", email)
+ .add("address", address)
+ .add("role", role)
+ .add("tag", tag)
+ .add("note", note)
+ .add("interviewDate", date)
+ .toString();
+ }
+
+}
diff --git a/src/main/java/hirehive/address/model/person/PersonContainsTagPredicate.java b/src/main/java/hirehive/address/model/person/PersonContainsTagPredicate.java
new file mode 100644
index 00000000000..3f49f1b67e7
--- /dev/null
+++ b/src/main/java/hirehive/address/model/person/PersonContainsTagPredicate.java
@@ -0,0 +1,47 @@
+package hirehive.address.model.person;
+
+import java.util.function.Predicate;
+
+import hirehive.address.commons.util.ToStringBuilder;
+import hirehive.address.logic.Messages;
+import hirehive.address.model.tag.Tag;
+
+/**
+ * Tests that a {@code Person}'s {@code Tag}s matches the given Tag.
+ */
+public class PersonContainsTagPredicate implements PersonPredicate {
+ private final Tag tag;
+ public PersonContainsTagPredicate(Tag tag) {
+ this.tag = tag;
+ }
+
+ @Override
+ public boolean test(Person person) {
+ return person.getTag().equals(tag);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof PersonContainsTagPredicate)) {
+ return false;
+ }
+
+ PersonContainsTagPredicate otherPersonContainsTagPredicate = (PersonContainsTagPredicate) other;
+ return this.tag.equals(otherPersonContainsTagPredicate.tag);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).add("tag", this.tag).toString();
+ }
+
+ @Override
+ public String getSuccessString() {
+ return String.format(Messages.MESSAGE_FILTER_OVERVIEW_TAG, tag);
+ }
+}
diff --git a/src/main/java/hirehive/address/model/person/PersonDoesNotContainTagPredicate.java b/src/main/java/hirehive/address/model/person/PersonDoesNotContainTagPredicate.java
new file mode 100644
index 00000000000..e914785f1b6
--- /dev/null
+++ b/src/main/java/hirehive/address/model/person/PersonDoesNotContainTagPredicate.java
@@ -0,0 +1,47 @@
+package hirehive.address.model.person;
+
+import hirehive.address.commons.util.ToStringBuilder;
+import hirehive.address.logic.Messages;
+import hirehive.address.model.tag.Tag;
+
+/**
+ * Tests that a Person's {@code tag}s do not match the given tag
+ */
+public class PersonDoesNotContainTagPredicate implements PersonPredicate {
+ private final Tag tag;
+
+ public PersonDoesNotContainTagPredicate(Tag tag) {
+ this.tag = tag;
+ }
+
+ @Override
+ public boolean test(Person person) {
+ return !person.getTag().equals(tag);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof PersonDoesNotContainTagPredicate)) {
+ return false;
+ }
+
+ PersonDoesNotContainTagPredicate otherPersonDoesNotContainTagPredicate =
+ (PersonDoesNotContainTagPredicate) other;
+ return this.tag.equals(otherPersonDoesNotContainTagPredicate.tag);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).add("tag", this.tag).toString();
+ }
+
+ @Override
+ public String getSuccessString() {
+ return String.format(Messages.MESSAGE_FILTEROUT_OVERVIEW_TAG, tag);
+ }
+}
diff --git a/src/main/java/hirehive/address/model/person/PersonPredicate.java b/src/main/java/hirehive/address/model/person/PersonPredicate.java
new file mode 100644
index 00000000000..e39d29ca506
--- /dev/null
+++ b/src/main/java/hirehive/address/model/person/PersonPredicate.java
@@ -0,0 +1,10 @@
+package hirehive.address.model.person;
+
+import java.util.function.Predicate;
+
+/**
+ * Interface used for predicates that operate on the Person class
+ */
+public interface PersonPredicate extends Predicate {
+ public String getSuccessString();
+}
diff --git a/src/main/java/seedu/address/model/person/Phone.java b/src/main/java/hirehive/address/model/person/Phone.java
similarity index 81%
rename from src/main/java/seedu/address/model/person/Phone.java
rename to src/main/java/hirehive/address/model/person/Phone.java
index d733f63d739..f42ea27ad9a 100644
--- a/src/main/java/seedu/address/model/person/Phone.java
+++ b/src/main/java/hirehive/address/model/person/Phone.java
@@ -1,7 +1,8 @@
-package seedu.address.model.person;
+package hirehive.address.model.person;
import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.AppUtil.checkArgument;
+
+import hirehive.address.commons.util.AppUtil;
/**
* Represents a Person's phone number in the address book.
@@ -11,8 +12,8 @@ public class Phone {
public static final String MESSAGE_CONSTRAINTS =
- "Phone numbers should only contain numbers, and it should be at least 3 digits long";
- public static final String VALIDATION_REGEX = "\\d{3,}";
+ "Phone numbers should only contain numbers, and it should be an 8 digit number starting with 8, 9 or 6";
+ public static final String VALIDATION_REGEX = "[896]\\d{7}";
public final String value;
/**
@@ -22,7 +23,7 @@ public class Phone {
*/
public Phone(String phone) {
requireNonNull(phone);
- checkArgument(isValidPhone(phone), MESSAGE_CONSTRAINTS);
+ AppUtil.checkArgument(isValidPhone(phone), MESSAGE_CONSTRAINTS);
value = phone;
}
diff --git a/src/main/java/hirehive/address/model/person/Role.java b/src/main/java/hirehive/address/model/person/Role.java
new file mode 100644
index 00000000000..88e93b1c0c3
--- /dev/null
+++ b/src/main/java/hirehive/address/model/person/Role.java
@@ -0,0 +1,67 @@
+package hirehive.address.model.person;
+
+import static java.util.Objects.requireNonNull;
+
+import hirehive.address.commons.util.AppUtil;
+
+/**
+ * Represents a Person's role in the address book.
+ * Guarantees: immutable; is valid as declared in {@link #isValidRole(String)}
+ */
+public class Role {
+ public static final String MESSAGE_CONSTRAINTS =
+ "Roles should only contain alphanumeric characters and spaces, and it should not be blank";
+
+ /*
+ * The first character of the address must not be a whitespace,
+ * otherwise " " (a blank string) becomes a valid input.
+ */
+ public static final String VALIDATION_REGEX = "[\\p{Alnum}][\\p{Alnum} ]*";
+ public final String fullRole;
+
+ /**
+ * Constructs a {@code Role}.
+ *
+ * @param role A valid role.
+ */
+ public Role(String role) {
+ requireNonNull(role);
+ AppUtil.checkArgument(isValidRole(role), MESSAGE_CONSTRAINTS);
+ fullRole = role;
+ }
+
+ /**
+ * Returns true if a given string is a valid role.
+ *
+ * @param test The string to test.
+ * @return true if the string matches the role name format; false otherwise.
+ */
+ public static boolean isValidRole(String test) {
+ return test.matches(VALIDATION_REGEX);
+ }
+
+ @Override
+ public String toString() {
+ return fullRole;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof Role)) {
+ return false;
+ }
+
+ Role otherRole = (Role) other;
+ return fullRole.equals(otherRole.fullRole);
+ }
+
+ @Override
+ public int hashCode() {
+ return fullRole.hashCode();
+ }
+}
diff --git a/src/main/java/seedu/address/model/person/UniquePersonList.java b/src/main/java/hirehive/address/model/person/UniquePersonList.java
similarity index 92%
rename from src/main/java/seedu/address/model/person/UniquePersonList.java
rename to src/main/java/hirehive/address/model/person/UniquePersonList.java
index cc0a68d79f9..8242462dc46 100644
--- a/src/main/java/seedu/address/model/person/UniquePersonList.java
+++ b/src/main/java/hirehive/address/model/person/UniquePersonList.java
@@ -1,15 +1,15 @@
-package seedu.address.model.person;
+package hirehive.address.model.person;
import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
import java.util.Iterator;
import java.util.List;
+import hirehive.address.commons.util.CollectionUtil;
+import hirehive.address.model.person.exceptions.DuplicatePersonException;
+import hirehive.address.model.person.exceptions.PersonNotFoundException;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
-import seedu.address.model.person.exceptions.DuplicatePersonException;
-import seedu.address.model.person.exceptions.PersonNotFoundException;
/**
* A list of persons that enforces uniqueness between its elements and does not allow nulls.
@@ -54,7 +54,7 @@ public void add(Person toAdd) {
* The person identity of {@code editedPerson} must not be the same as another existing person in the list.
*/
public void setPerson(Person target, Person editedPerson) {
- requireAllNonNull(target, editedPerson);
+ CollectionUtil.requireAllNonNull(target, editedPerson);
int index = internalList.indexOf(target);
if (index == -1) {
@@ -89,7 +89,7 @@ public void setPersons(UniquePersonList replacement) {
* {@code persons} must not contain duplicate persons.
*/
public void setPersons(List persons) {
- requireAllNonNull(persons);
+ CollectionUtil.requireAllNonNull(persons);
if (!personsAreUnique(persons)) {
throw new DuplicatePersonException();
}
diff --git a/src/main/java/hirehive/address/model/person/UpcomingInterviewPredicate.java b/src/main/java/hirehive/address/model/person/UpcomingInterviewPredicate.java
new file mode 100644
index 00000000000..f10b2b4d7dc
--- /dev/null
+++ b/src/main/java/hirehive/address/model/person/UpcomingInterviewPredicate.java
@@ -0,0 +1,62 @@
+package hirehive.address.model.person;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+
+import hirehive.address.logic.Messages;
+
+/**
+ * Tests that a {@code Person}'s {@code InterviewDate} is within the given amount of days from the current date.
+ */
+public class UpcomingInterviewPredicate implements PersonPredicate {
+ public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy");
+ private final int days;
+ private final LocalDate currDay;
+
+ /**
+ * Default constructor for {@code UpcomingInterviewPredicate}
+ * @param days Number of days to query for
+ */
+ public UpcomingInterviewPredicate(int days) {
+ currDay = LocalDate.now();
+ this.days = days;
+ }
+
+ /**
+ * Testing constructor for {@code UpcomingInterviewPredicate}, allows setting of current day to given value
+ * @param days Number of days to query for
+ * @param currDay Initialized date to query from
+ */
+ public UpcomingInterviewPredicate(int days, String currDay) {
+ this.currDay = LocalDate.parse(currDay, DATE_TIME_FORMATTER);
+ this.days = days;
+ }
+
+ @Override
+ public boolean test(Person person) {
+ return person.getDate().value.map(date -> ChronoUnit.DAYS.between(currDay, date))
+ .map(days -> days <= this.days && days >= 0)
+ .orElse(false);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof UpcomingInterviewPredicate)) {
+ return false;
+ }
+
+ UpcomingInterviewPredicate otherUpcomingInterviewPredicate = (UpcomingInterviewPredicate) other;
+ return this.days == otherUpcomingInterviewPredicate.days && this.currDay.equals(otherUpcomingInterviewPredicate.currDay);
+ }
+
+ @Override
+ public String getSuccessString() {
+ return String.format(Messages.MESSAGE_FILTER_OVERVIEW_DATE, days);
+ }
+}
diff --git a/src/main/java/seedu/address/model/person/exceptions/DuplicatePersonException.java b/src/main/java/hirehive/address/model/person/exceptions/DuplicatePersonException.java
similarity index 86%
rename from src/main/java/seedu/address/model/person/exceptions/DuplicatePersonException.java
rename to src/main/java/hirehive/address/model/person/exceptions/DuplicatePersonException.java
index d7290f59442..b2feaa03986 100644
--- a/src/main/java/seedu/address/model/person/exceptions/DuplicatePersonException.java
+++ b/src/main/java/hirehive/address/model/person/exceptions/DuplicatePersonException.java
@@ -1,4 +1,4 @@
-package seedu.address.model.person.exceptions;
+package hirehive.address.model.person.exceptions;
/**
* Signals that the operation will result in duplicate Persons (Persons are considered duplicates if they have the same
diff --git a/src/main/java/seedu/address/model/person/exceptions/PersonNotFoundException.java b/src/main/java/hirehive/address/model/person/exceptions/PersonNotFoundException.java
similarity index 74%
rename from src/main/java/seedu/address/model/person/exceptions/PersonNotFoundException.java
rename to src/main/java/hirehive/address/model/person/exceptions/PersonNotFoundException.java
index fa764426ca7..8c8952cbbf1 100644
--- a/src/main/java/seedu/address/model/person/exceptions/PersonNotFoundException.java
+++ b/src/main/java/hirehive/address/model/person/exceptions/PersonNotFoundException.java
@@ -1,4 +1,4 @@
-package seedu.address.model.person.exceptions;
+package hirehive.address.model.person.exceptions;
/**
* Signals that the operation is unable to find the specified person.
diff --git a/src/main/java/hirehive/address/model/tag/Tag.java b/src/main/java/hirehive/address/model/tag/Tag.java
new file mode 100644
index 00000000000..4e64cb60974
--- /dev/null
+++ b/src/main/java/hirehive/address/model/tag/Tag.java
@@ -0,0 +1,63 @@
+package hirehive.address.model.tag;
+
+/**
+ * Represents a Tag in the address book.
+ */
+
+public enum Tag {
+ APPLICANT("Applicant"),
+ CANDIDATE("Candidate"),
+ INTERVIEWEE("Interviewee"),
+ OFFERED("Offered"),
+ REJECTED("Rejected");
+
+ public static final String MESSAGE_CONSTRAINTS = "Tag should be one of the following:\n"
+ + " 1. Applicant\n"
+ + " 2. Candidate\n"
+ + " 3. Interviewee\n"
+ + " 4. Offered\n"
+ + " 5. Rejected\n";
+
+ private static final Tag DEFAULT_TAG = APPLICANT;
+
+ public final String tagName;
+
+ Tag(String tagName) {
+ this.tagName = tagName;
+ }
+
+ public String getTagName() {
+ return tagName;
+ }
+
+ public static Tag getDefaultTag() {
+ return DEFAULT_TAG;
+ }
+
+ /**
+ * Gets the tag of the hiring stage that is offset from this tag
+ * @param offset of the wanted hiring stage tag from this tag
+ * @return tag that is offset from this tag
+ */
+ public Tag offsetBy(int offset) {
+ if (offset == 0) {
+ return this;
+ }
+ if (offset > 0) {
+ return switch (this) {
+ case REJECTED -> Tag.APPLICANT.offsetBy(offset - 1);
+ case APPLICANT -> Tag.CANDIDATE.offsetBy(offset - 1);
+ case CANDIDATE -> Tag.INTERVIEWEE.offsetBy(offset - 1);
+ case INTERVIEWEE -> Tag.OFFERED.offsetBy(offset - 1);
+ case OFFERED -> this;
+ };
+ }
+ return switch (this) {
+ case REJECTED -> this;
+ case APPLICANT -> Tag.REJECTED.offsetBy(offset + 1);
+ case CANDIDATE -> Tag.APPLICANT.offsetBy(offset + 1);
+ case INTERVIEWEE -> Tag.CANDIDATE.offsetBy(offset + 1);
+ case OFFERED -> Tag.INTERVIEWEE.offsetBy(offset + 1);
+ };
+ }
+}
diff --git a/src/main/java/hirehive/address/model/util/SampleDataUtil.java b/src/main/java/hirehive/address/model/util/SampleDataUtil.java
new file mode 100644
index 00000000000..6a749432f1a
--- /dev/null
+++ b/src/main/java/hirehive/address/model/util/SampleDataUtil.java
@@ -0,0 +1,54 @@
+package hirehive.address.model.util;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import hirehive.address.logic.parser.ParserUtil;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.ReadOnlyAddressBook;
+import hirehive.address.model.person.Address;
+import hirehive.address.model.person.Email;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.Name;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.person.Phone;
+import hirehive.address.model.person.Role;
+import hirehive.address.model.tag.Tag;
+
+/**
+ * Contains utility methods for populating {@code AddressBook} with sample data.
+ */
+public class SampleDataUtil {
+ public static Person[] getSamplePersons() {
+ return new Person[] {
+ new Person(new Name("Alice Yeoh"), new Phone("87438807"), new Email("alexyeoh@example.com"),
+ new Address("Blk 30 Geylang Street 29, #06-40"), new Role("UI designer"),
+ Tag.APPLICANT, new Note("20 years old"), new InterviewDate()),
+ new Person(new Name("Bernice Yu"), new Phone("99272758"), new Email("berniceyu@example.com"),
+ new Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"), new Role("HR manager"),
+ Tag.INTERVIEWEE, new Note(""), new InterviewDate("01/03/2025")),
+ new Person(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Email("charlotte@example.com"),
+ new Address("Blk 11 Ang Mo Kio Street 74, #11-04"), new Role("HR manager"),
+ Tag.CANDIDATE, new Note(""), new InterviewDate()),
+ new Person(new Name("David Li"), new Phone("91031282"), new Email("lidavid@example.com"),
+ new Address("Blk 436 Serangoon Gardens Street 26, #16-43"), new Role("Software Engineer"),
+ Tag.OFFERED, new Note(""), new InterviewDate("06/07/2025")),
+ new Person(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"),
+ new Address("Blk 47 Tampines Street 20, #17-35"), new Role("Software Engineer"),
+ Tag.REJECTED, new Note("30 years old"), new InterviewDate("06/03/2025")),
+ new Person(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"),
+ new Address("Blk 45 Aljunied Street 85, #11-31"), new Role("Cybersecurity specialist"),
+ Tag.APPLICANT, new Note(""), new InterviewDate())
+ };
+ }
+
+ public static ReadOnlyAddressBook getSampleAddressBook() {
+ AddressBook sampleAb = new AddressBook();
+ for (Person samplePerson : getSamplePersons()) {
+ sampleAb.addPerson(samplePerson);
+ }
+ return sampleAb;
+ }
+}
diff --git a/src/main/java/seedu/address/storage/AddressBookStorage.java b/src/main/java/hirehive/address/storage/AddressBookStorage.java
similarity index 82%
rename from src/main/java/seedu/address/storage/AddressBookStorage.java
rename to src/main/java/hirehive/address/storage/AddressBookStorage.java
index f2e015105ae..c393c276c0e 100644
--- a/src/main/java/seedu/address/storage/AddressBookStorage.java
+++ b/src/main/java/hirehive/address/storage/AddressBookStorage.java
@@ -1,14 +1,15 @@
-package seedu.address.storage;
+package hirehive.address.storage;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.model.ReadOnlyAddressBook;
+import hirehive.address.commons.exceptions.DataLoadingException;
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.ReadOnlyAddressBook;
/**
- * Represents a storage for {@link seedu.address.model.AddressBook}.
+ * Represents a storage for {@link AddressBook}.
*/
public interface AddressBookStorage {
diff --git a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java b/src/main/java/hirehive/address/storage/JsonAdaptedPerson.java
similarity index 55%
rename from src/main/java/seedu/address/storage/JsonAdaptedPerson.java
rename to src/main/java/hirehive/address/storage/JsonAdaptedPerson.java
index bd1ca0f56c8..948fc85d17c 100644
--- a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java
+++ b/src/main/java/hirehive/address/storage/JsonAdaptedPerson.java
@@ -1,4 +1,4 @@
-package seedu.address.storage;
+package hirehive.address.storage;
import java.util.ArrayList;
import java.util.HashSet;
@@ -9,13 +9,17 @@
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
+import hirehive.address.commons.exceptions.IllegalValueException;
+import hirehive.address.logic.parser.ParserUtil;
+import hirehive.address.model.person.Address;
+import hirehive.address.model.person.Email;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.Name;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.person.Phone;
+import hirehive.address.model.person.Role;
+import hirehive.address.model.tag.Tag;
/**
* Jackson-friendly version of {@link Person}.
@@ -28,7 +32,10 @@ class JsonAdaptedPerson {
private final String phone;
private final String email;
private final String address;
- private final List tags = new ArrayList<>();
+ private final String role;
+ private final String tag;
+ private final String note;
+ private final String date;
/**
* Constructs a {@code JsonAdaptedPerson} with the given person details.
@@ -36,14 +43,16 @@ class JsonAdaptedPerson {
@JsonCreator
public JsonAdaptedPerson(@JsonProperty("name") String name, @JsonProperty("phone") String phone,
@JsonProperty("email") String email, @JsonProperty("address") String address,
- @JsonProperty("tags") List tags) {
+ @JsonProperty("role") String role, @JsonProperty("tag") String tag,
+ @JsonProperty("note") String note, @JsonProperty("date") String date) {
this.name = name;
this.phone = phone;
this.email = email;
this.address = address;
- if (tags != null) {
- this.tags.addAll(tags);
- }
+ this.role = role;
+ this.tag = tag;
+ this.note = note;
+ this.date = date;
}
/**
@@ -54,9 +63,10 @@ public JsonAdaptedPerson(Person source) {
phone = source.getPhone().value;
email = source.getEmail().value;
address = source.getAddress().value;
- tags.addAll(source.getTags().stream()
- .map(JsonAdaptedTag::new)
- .collect(Collectors.toList()));
+ role = source.getRole().fullRole;
+ tag = source.getTag().getTagName();
+ note = source.getNote().value;
+ date = source.getDate().toString();
}
/**
@@ -65,11 +75,6 @@ public JsonAdaptedPerson(Person source) {
* @throws IllegalValueException if there were any data constraints violated in the adapted person.
*/
public Person toModelType() throws IllegalValueException {
- final List personTags = new ArrayList<>();
- for (JsonAdaptedTag tag : tags) {
- personTags.add(tag.toModelType());
- }
-
if (name == null) {
throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName()));
}
@@ -102,8 +107,37 @@ public Person toModelType() throws IllegalValueException {
}
final Address modelAddress = new Address(address);
- final Set modelTags = new HashSet<>(personTags);
- return new Person(modelName, modelPhone, modelEmail, modelAddress, modelTags);
+ if (role == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Role.class.getSimpleName()));
+ }
+ if (!Role.isValidRole(role)) {
+ throw new IllegalValueException(Role.MESSAGE_CONSTRAINTS);
+ }
+ final Role modelRole = new Role(role);
+
+ if (tag == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Tag.class.getSimpleName()));
+ }
+ final Tag modelTag = ParserUtil.parseTag(tag);
+
+ if (note == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Note.class.getSimpleName()));
+ }
+ if (!Note.isValidNote(note)) {
+ throw new IllegalValueException(Note.MESSAGE_CONSTRAINTS);
+ }
+ final Note modelNote = new Note(note);
+
+ if (date == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT,
+ InterviewDate.class.getSimpleName()));
+ }
+ if (!InterviewDate.isValidDate(date)) {
+ throw new IllegalValueException(InterviewDate.MESSAGE_CONSTRAINTS);
+ }
+ final InterviewDate modelDate = new InterviewDate(date);
+
+ return new Person(modelName, modelPhone, modelEmail, modelAddress, modelRole, modelTag, modelNote, modelDate);
}
}
diff --git a/src/main/java/seedu/address/storage/JsonAdaptedTag.java b/src/main/java/hirehive/address/storage/JsonAdaptedTag.java
similarity index 73%
rename from src/main/java/seedu/address/storage/JsonAdaptedTag.java
rename to src/main/java/hirehive/address/storage/JsonAdaptedTag.java
index 0df22bdb754..2a2ee159fb2 100644
--- a/src/main/java/seedu/address/storage/JsonAdaptedTag.java
+++ b/src/main/java/hirehive/address/storage/JsonAdaptedTag.java
@@ -1,10 +1,12 @@
-package seedu.address.storage;
+package hirehive.address.storage;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.model.tag.Tag;
+import hirehive.address.commons.exceptions.IllegalValueException;
+import hirehive.address.logic.parser.ParserUtil;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.tag.Tag;
/**
* Jackson-friendly version of {@link Tag}.
@@ -39,10 +41,9 @@ public String getTagName() {
* @throws IllegalValueException if there were any data constraints violated in the adapted tag.
*/
public Tag toModelType() throws IllegalValueException {
- if (!Tag.isValidTagName(tagName)) {
- throw new IllegalValueException(Tag.MESSAGE_CONSTRAINTS);
- }
- return new Tag(tagName);
+ Tag tag;
+ tag = ParserUtil.parseTag(tagName);
+ return tag;
}
}
diff --git a/src/main/java/seedu/address/storage/JsonAddressBookStorage.java b/src/main/java/hirehive/address/storage/JsonAddressBookStorage.java
similarity index 86%
rename from src/main/java/seedu/address/storage/JsonAddressBookStorage.java
rename to src/main/java/hirehive/address/storage/JsonAddressBookStorage.java
index 41e06f264e1..323299c431c 100644
--- a/src/main/java/seedu/address/storage/JsonAddressBookStorage.java
+++ b/src/main/java/hirehive/address/storage/JsonAddressBookStorage.java
@@ -1,4 +1,4 @@
-package seedu.address.storage;
+package hirehive.address.storage;
import static java.util.Objects.requireNonNull;
@@ -7,12 +7,12 @@
import java.util.Optional;
import java.util.logging.Logger;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.commons.util.FileUtil;
-import seedu.address.commons.util.JsonUtil;
-import seedu.address.model.ReadOnlyAddressBook;
+import hirehive.address.commons.core.LogsCenter;
+import hirehive.address.commons.exceptions.DataLoadingException;
+import hirehive.address.commons.exceptions.IllegalValueException;
+import hirehive.address.commons.util.FileUtil;
+import hirehive.address.commons.util.JsonUtil;
+import hirehive.address.model.ReadOnlyAddressBook;
/**
* A class to access AddressBook data stored as a json file on the hard disk.
diff --git a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java b/src/main/java/hirehive/address/storage/JsonSerializableAddressBook.java
similarity index 88%
rename from src/main/java/seedu/address/storage/JsonSerializableAddressBook.java
rename to src/main/java/hirehive/address/storage/JsonSerializableAddressBook.java
index 5efd834091d..d07ff363354 100644
--- a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java
+++ b/src/main/java/hirehive/address/storage/JsonSerializableAddressBook.java
@@ -1,4 +1,4 @@
-package seedu.address.storage;
+package hirehive.address.storage;
import java.util.ArrayList;
import java.util.List;
@@ -8,10 +8,10 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRootName;
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.model.AddressBook;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.person.Person;
+import hirehive.address.commons.exceptions.IllegalValueException;
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.ReadOnlyAddressBook;
+import hirehive.address.model.person.Person;
/**
* An Immutable AddressBook that is serializable to JSON format.
diff --git a/src/main/java/seedu/address/storage/JsonUserPrefsStorage.java b/src/main/java/hirehive/address/storage/JsonUserPrefsStorage.java
similarity index 82%
rename from src/main/java/seedu/address/storage/JsonUserPrefsStorage.java
rename to src/main/java/hirehive/address/storage/JsonUserPrefsStorage.java
index 48a9754807d..fdfa50d3b49 100644
--- a/src/main/java/seedu/address/storage/JsonUserPrefsStorage.java
+++ b/src/main/java/hirehive/address/storage/JsonUserPrefsStorage.java
@@ -1,13 +1,13 @@
-package seedu.address.storage;
+package hirehive.address.storage;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.commons.util.JsonUtil;
-import seedu.address.model.ReadOnlyUserPrefs;
-import seedu.address.model.UserPrefs;
+import hirehive.address.commons.exceptions.DataLoadingException;
+import hirehive.address.commons.util.JsonUtil;
+import hirehive.address.model.ReadOnlyUserPrefs;
+import hirehive.address.model.UserPrefs;
/**
* A class to access UserPrefs stored in the hard disk as a json file
diff --git a/src/main/java/seedu/address/storage/Storage.java b/src/main/java/hirehive/address/storage/Storage.java
similarity index 71%
rename from src/main/java/seedu/address/storage/Storage.java
rename to src/main/java/hirehive/address/storage/Storage.java
index 9fba0c7a1d6..d5680e133b9 100644
--- a/src/main/java/seedu/address/storage/Storage.java
+++ b/src/main/java/hirehive/address/storage/Storage.java
@@ -1,13 +1,13 @@
-package seedu.address.storage;
+package hirehive.address.storage;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.ReadOnlyUserPrefs;
-import seedu.address.model.UserPrefs;
+import hirehive.address.commons.exceptions.DataLoadingException;
+import hirehive.address.model.ReadOnlyAddressBook;
+import hirehive.address.model.ReadOnlyUserPrefs;
+import hirehive.address.model.UserPrefs;
/**
* API of the Storage component
diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/hirehive/address/storage/StorageManager.java
similarity index 89%
rename from src/main/java/seedu/address/storage/StorageManager.java
rename to src/main/java/hirehive/address/storage/StorageManager.java
index 8b84a9024d5..0147021ddd6 100644
--- a/src/main/java/seedu/address/storage/StorageManager.java
+++ b/src/main/java/hirehive/address/storage/StorageManager.java
@@ -1,15 +1,15 @@
-package seedu.address.storage;
+package hirehive.address.storage;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
import java.util.logging.Logger;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.ReadOnlyUserPrefs;
-import seedu.address.model.UserPrefs;
+import hirehive.address.commons.core.LogsCenter;
+import hirehive.address.commons.exceptions.DataLoadingException;
+import hirehive.address.model.ReadOnlyAddressBook;
+import hirehive.address.model.ReadOnlyUserPrefs;
+import hirehive.address.model.UserPrefs;
/**
* Manages storage of AddressBook data in local storage.
diff --git a/src/main/java/seedu/address/storage/UserPrefsStorage.java b/src/main/java/hirehive/address/storage/UserPrefsStorage.java
similarity index 69%
rename from src/main/java/seedu/address/storage/UserPrefsStorage.java
rename to src/main/java/hirehive/address/storage/UserPrefsStorage.java
index e94ca422ea8..e82457389d2 100644
--- a/src/main/java/seedu/address/storage/UserPrefsStorage.java
+++ b/src/main/java/hirehive/address/storage/UserPrefsStorage.java
@@ -1,15 +1,15 @@
-package seedu.address.storage;
+package hirehive.address.storage;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.model.ReadOnlyUserPrefs;
-import seedu.address.model.UserPrefs;
+import hirehive.address.commons.exceptions.DataLoadingException;
+import hirehive.address.model.ReadOnlyUserPrefs;
+import hirehive.address.model.UserPrefs;
/**
- * Represents a storage for {@link seedu.address.model.UserPrefs}.
+ * Represents a storage for {@link UserPrefs}.
*/
public interface UserPrefsStorage {
@@ -27,7 +27,7 @@ public interface UserPrefsStorage {
Optional readUserPrefs() throws DataLoadingException;
/**
- * Saves the given {@link seedu.address.model.ReadOnlyUserPrefs} to the storage.
+ * Saves the given {@link ReadOnlyUserPrefs} to the storage.
* @param userPrefs cannot be null.
* @throws IOException if there was any problem writing to the file.
*/
diff --git a/src/main/java/seedu/address/ui/CommandBox.java b/src/main/java/hirehive/address/ui/CommandBox.java
similarity index 88%
rename from src/main/java/seedu/address/ui/CommandBox.java
rename to src/main/java/hirehive/address/ui/CommandBox.java
index 9e75478664b..7c9bef7a5f3 100644
--- a/src/main/java/seedu/address/ui/CommandBox.java
+++ b/src/main/java/hirehive/address/ui/CommandBox.java
@@ -1,12 +1,13 @@
-package seedu.address.ui;
+package hirehive.address.ui;
+import hirehive.address.logic.Logic;
+import hirehive.address.logic.commands.CommandResult;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.parser.exceptions.ParseException;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
import javafx.scene.layout.Region;
-import seedu.address.logic.commands.CommandResult;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.logic.parser.exceptions.ParseException;
/**
* The UI component that is responsible for receiving user command inputs.
@@ -77,7 +78,7 @@ public interface CommandExecutor {
/**
* Executes the command and returns the result.
*
- * @see seedu.address.logic.Logic#execute(String)
+ * @see Logic#execute(String)
*/
CommandResult execute(String commandText) throws CommandException, ParseException;
}
diff --git a/src/main/java/seedu/address/ui/HelpWindow.java b/src/main/java/hirehive/address/ui/HelpWindow.java
similarity index 92%
rename from src/main/java/seedu/address/ui/HelpWindow.java
rename to src/main/java/hirehive/address/ui/HelpWindow.java
index 3f16b2fcf26..4031277c4a0 100644
--- a/src/main/java/seedu/address/ui/HelpWindow.java
+++ b/src/main/java/hirehive/address/ui/HelpWindow.java
@@ -1,21 +1,21 @@
-package seedu.address.ui;
+package hirehive.address.ui;
import java.util.logging.Logger;
+import hirehive.address.commons.core.LogsCenter;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.stage.Stage;
-import seedu.address.commons.core.LogsCenter;
/**
* Controller for a help page
*/
public class HelpWindow extends UiPart {
- public static final String USERGUIDE_URL = "https://se-education.org/addressbook-level3/UserGuide.html";
+ public static final String USERGUIDE_URL = "https://ay2425s2-cs2103t-f13-3.github.io/tp/UserGuide.html";
public static final String HELP_MESSAGE = "Refer to the user guide: " + USERGUIDE_URL;
private static final Logger logger = LogsCenter.getLogger(HelpWindow.class);
diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/hirehive/address/ui/MainWindow.java
similarity index 67%
rename from src/main/java/seedu/address/ui/MainWindow.java
rename to src/main/java/hirehive/address/ui/MainWindow.java
index 79e74ef37c0..db26603670b 100644
--- a/src/main/java/seedu/address/ui/MainWindow.java
+++ b/src/main/java/hirehive/address/ui/MainWindow.java
@@ -1,21 +1,32 @@
-package seedu.address.ui;
+package hirehive.address.ui;
+
+import static hirehive.address.logic.Messages.MESSAGE_DATA_SAVED;
+import static hirehive.address.logic.Messages.MESSAGE_EMPTY_ADDRESS_BOOK;
+import static hirehive.address.logic.Messages.MESSAGE_LOAD_SUCCESS;
+import static hirehive.address.logic.Messages.MESSAGE_SAMPLE_ADDRESS_BOOK;
import java.util.logging.Logger;
+import hirehive.address.commons.core.GuiSettings;
+import hirehive.address.commons.core.LogsCenter;
+import hirehive.address.logic.Logic;
+import hirehive.address.logic.commands.CommandResult;
+import hirehive.address.logic.commands.ExitCommand;
+import hirehive.address.logic.commands.ListCommand;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.ReadOnlyAddressBook;
+import hirehive.address.model.util.SampleDataUtil;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
+import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextInputControl;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.logic.Logic;
-import seedu.address.logic.commands.CommandResult;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.logic.parser.exceptions.ParseException;
/**
* The Main Window. Provides the basic application layout containing
@@ -34,6 +45,7 @@ public class MainWindow extends UiPart {
private PersonListPanel personListPanel;
private ResultDisplay resultDisplay;
private HelpWindow helpWindow;
+ private NoteWindow noteWindow;
@FXML
private StackPane commandBoxPlaceholder;
@@ -50,6 +62,9 @@ public class MainWindow extends UiPart {
@FXML
private StackPane statusbarPlaceholder;
+ @FXML
+ private Label contactCountLabel;
+
/**
* Creates a {@code MainWindow} with the given {@code Stage} and {@code Logic}.
*/
@@ -66,6 +81,7 @@ public MainWindow(Stage primaryStage, Logic logic) {
setAccelerators();
helpWindow = new HelpWindow();
+ noteWindow = new NoteWindow();
}
public Stage getPrimaryStage() {
@@ -113,9 +129,13 @@ void fillInnerParts() {
personListPanel = new PersonListPanel(logic.getFilteredPersonList());
personListPanelPlaceholder.getChildren().add(personListPanel.getRoot());
+ updateContactCount();
+
resultDisplay = new ResultDisplay();
resultDisplayPlaceholder.getChildren().add(resultDisplay.getRoot());
+ loadAddressBookMessage();
+
StatusBarFooter statusBarFooter = new StatusBarFooter(logic.getAddressBookFilePath());
statusbarPlaceholder.getChildren().add(statusBarFooter.getRoot());
@@ -147,6 +167,18 @@ public void handleHelp() {
}
}
+ /**
+ * Opens the note window or focuses on it if it's already opened.
+ */
+ @FXML
+ public void handleNote() {
+ if (!noteWindow.isShowing()) {
+ noteWindow.show();
+ } else {
+ noteWindow.focus();
+ }
+ }
+
void show() {
primaryStage.show();
}
@@ -159,6 +191,7 @@ private void handleExit() {
GuiSettings guiSettings = new GuiSettings(primaryStage.getWidth(), primaryStage.getHeight(),
(int) primaryStage.getX(), (int) primaryStage.getY());
logic.setGuiSettings(guiSettings);
+ noteWindow.hide();
helpWindow.hide();
primaryStage.hide();
}
@@ -170,13 +203,21 @@ public PersonListPanel getPersonListPanel() {
/**
* Executes the command and returns the result.
*
- * @see seedu.address.logic.Logic#execute(String)
+ * @see Logic#execute(String)
*/
private CommandResult executeCommand(String commandText) throws CommandException, ParseException {
try {
CommandResult commandResult = logic.execute(commandText);
logger.info("Result: " + commandResult.getFeedbackToUser());
- resultDisplay.setFeedbackToUser(commandResult.getFeedbackToUser());
+ String userFeedback = commandResult.getFeedbackToUser();
+ // if command has edited the applicant book in some way
+ if (commandResult.isChange()) {
+ userFeedback += MESSAGE_DATA_SAVED;
+ }
+ resultDisplay.setFeedbackToUser(userFeedback);
+ noteWindow.setNote(logic);
+
+ updateContactCount();
if (commandResult.isShowHelp()) {
handleHelp();
@@ -186,11 +227,38 @@ private CommandResult executeCommand(String commandText) throws CommandException
handleExit();
}
+ if (commandResult.isShowNote()) {
+ handleNote();
+ }
+
return commandResult;
} catch (CommandException | ParseException e) {
logger.info("An error occurred while executing command: " + commandText);
resultDisplay.setFeedbackToUser(e.getMessage());
+ updateContactCount();
throw e;
}
}
+
+ /**
+ * Displays status of addressBook in the results box in the GUI upon loading.
+ */
+ private void loadAddressBookMessage() {
+ ReadOnlyAddressBook currentAddressBook = logic.getAddressBook();
+ // Data file could not be read, loads empty AddressBook instead
+ if (currentAddressBook.equals(new AddressBook())) {
+ resultDisplay.setFeedbackToUser(MESSAGE_EMPTY_ADDRESS_BOOK);
+ // Data file does not exist, load sample AddressBook instead
+ } else if (currentAddressBook.equals(SampleDataUtil.getSampleAddressBook())) {
+ resultDisplay.setFeedbackToUser(MESSAGE_SAMPLE_ADDRESS_BOOK);
+ } else {
+ // Data file loaded successfully
+ resultDisplay.setFeedbackToUser(MESSAGE_LOAD_SUCCESS);
+ }
+ }
+
+ private void updateContactCount() {
+ int count = logic.getFilteredPersonListSize();
+ contactCountLabel.setText("Total contacts displayed: " + count);
+ }
}
diff --git a/src/main/java/hirehive/address/ui/NoteWindow.java b/src/main/java/hirehive/address/ui/NoteWindow.java
new file mode 100644
index 00000000000..e7caf9d76f6
--- /dev/null
+++ b/src/main/java/hirehive/address/ui/NoteWindow.java
@@ -0,0 +1,108 @@
+package hirehive.address.ui;
+
+import java.util.logging.Logger;
+
+import hirehive.address.commons.core.LogsCenter;
+import hirehive.address.logic.Logic;
+import hirehive.address.model.person.Note;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.TextArea;
+import javafx.scene.input.Clipboard;
+import javafx.scene.input.ClipboardContent;
+import javafx.stage.Stage;
+
+/**
+ * Controller for the note page.
+ */
+public class NoteWindow extends UiPart {
+
+ public static final String EMPTY_NOTE = "Currently empty...";
+
+ private static final Logger logger = LogsCenter.getLogger(NoteWindow.class);
+ private static final String FXML = "NoteWindow.fxml";
+
+ @FXML
+ private TextArea note;
+
+ @FXML
+ private Button save;
+
+ /**
+ * Creates a new NoteWindow.
+ * @param root Stage to use as the root of the NoteWindow.
+ */
+ public NoteWindow(Stage root) {
+ super(FXML, root);
+ note.setText(EMPTY_NOTE);
+ }
+
+ /**
+ * Creates a new NoteWindow.
+ */
+ public NoteWindow() {
+ this(new Stage());
+ }
+
+ /**
+ * Sets the note in the NoteWindow.
+ * @param logic from the MainWindow.
+ */
+ public void setNote(Logic logic) {
+ Note newNote = logic.getPersonNote();
+ if (newNote.isEmpty()) {
+ note.setText(EMPTY_NOTE);
+ note.setStyle("-fx-text-fill: yellow;");
+ } else {
+ note.setText(newNote.value);
+ note.setStyle("-fx-text-fill: white;");
+ }
+ }
+
+ /**
+ * Shows the NoteWindow.
+ */
+ public void show() {
+ logger.fine("Showing note page.");
+ getRoot().show();
+ getRoot().centerOnScreen();
+ }
+
+ /**
+ * Returns true if the note window is currently being shown.
+ */
+ public boolean isShowing() {
+ return getRoot().isShowing();
+ }
+
+ /**
+ * Hides the note window.
+ */
+ public void hide() {
+ note.setText(EMPTY_NOTE);
+ getRoot().hide();
+ }
+
+ /**
+ * Focuses on the note window.
+ */
+ public void focus() {
+ getRoot().requestFocus();
+ }
+
+ /**
+ * Copies the contents of the note to the clipboard.
+ */
+ @FXML
+ public void copyNote() {
+ final Clipboard clipboard = Clipboard.getSystemClipboard();
+ final ClipboardContent noteText = new ClipboardContent();
+ if (note.getStyle().equals("-fx-text-fill: white;")) {
+ noteText.putString(note.getText());
+ } else {
+ noteText.putString("");
+ }
+ clipboard.setContent(noteText);
+ }
+
+}
diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/hirehive/address/ui/PersonCard.java
similarity index 71%
rename from src/main/java/seedu/address/ui/PersonCard.java
rename to src/main/java/hirehive/address/ui/PersonCard.java
index 094c42cda82..a8f8fa87609 100644
--- a/src/main/java/seedu/address/ui/PersonCard.java
+++ b/src/main/java/hirehive/address/ui/PersonCard.java
@@ -1,13 +1,13 @@
-package seedu.address.ui;
+package hirehive.address.ui;
import java.util.Comparator;
+import hirehive.address.model.person.Person;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
-import seedu.address.model.person.Person;
/**
* An UI component that displays information of a {@code Person}.
@@ -39,7 +39,13 @@ public class PersonCard extends UiPart {
@FXML
private Label email;
@FXML
+ private Label role;
+ @FXML
private FlowPane tags;
+ @FXML
+ private Label date;
+ @FXML
+ private Label note;
/**
* Creates a {@code PersonCode} with the given {@code Person} and index to display.
@@ -52,8 +58,11 @@ public PersonCard(Person person, int displayedIndex) {
phone.setText(person.getPhone().value);
address.setText(person.getAddress().value);
email.setText(person.getEmail().value);
- person.getTags().stream()
- .sorted(Comparator.comparing(tag -> tag.tagName))
- .forEach(tag -> tags.getChildren().add(new Label(tag.tagName)));
+ role.setText(person.getRole().toString());
+ Label tag = new Label(person.getTag().getTagName());
+ tag.getStyleClass().add(person.getTag().getTagName().toLowerCase());
+ tags.getChildren().add(tag);
+ date.setText(person.getDate().toString().isBlank() ? "Date not set" : person.getDate().toString());
+ note.setText("Note Contents: " + (person.getNote().isEmpty() ? "Empty" : "Not empty"));
}
}
diff --git a/src/main/java/seedu/address/ui/PersonListPanel.java b/src/main/java/hirehive/address/ui/PersonListPanel.java
similarity index 91%
rename from src/main/java/seedu/address/ui/PersonListPanel.java
rename to src/main/java/hirehive/address/ui/PersonListPanel.java
index f4c501a897b..085b8277876 100644
--- a/src/main/java/seedu/address/ui/PersonListPanel.java
+++ b/src/main/java/hirehive/address/ui/PersonListPanel.java
@@ -1,14 +1,14 @@
-package seedu.address.ui;
+package hirehive.address.ui;
import java.util.logging.Logger;
+import hirehive.address.commons.core.LogsCenter;
+import hirehive.address.model.person.Person;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.Region;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.model.person.Person;
/**
* Panel containing the list of persons.
diff --git a/src/main/java/seedu/address/ui/ResultDisplay.java b/src/main/java/hirehive/address/ui/ResultDisplay.java
similarity index 95%
rename from src/main/java/seedu/address/ui/ResultDisplay.java
rename to src/main/java/hirehive/address/ui/ResultDisplay.java
index 7d98e84eedf..4d6b6f613c6 100644
--- a/src/main/java/seedu/address/ui/ResultDisplay.java
+++ b/src/main/java/hirehive/address/ui/ResultDisplay.java
@@ -1,4 +1,4 @@
-package seedu.address.ui;
+package hirehive.address.ui;
import static java.util.Objects.requireNonNull;
diff --git a/src/main/java/seedu/address/ui/StatusBarFooter.java b/src/main/java/hirehive/address/ui/StatusBarFooter.java
similarity index 95%
rename from src/main/java/seedu/address/ui/StatusBarFooter.java
rename to src/main/java/hirehive/address/ui/StatusBarFooter.java
index b577f829423..bb31a56b0fd 100644
--- a/src/main/java/seedu/address/ui/StatusBarFooter.java
+++ b/src/main/java/hirehive/address/ui/StatusBarFooter.java
@@ -1,4 +1,4 @@
-package seedu.address.ui;
+package hirehive.address.ui;
import java.nio.file.Path;
import java.nio.file.Paths;
diff --git a/src/main/java/seedu/address/ui/Ui.java b/src/main/java/hirehive/address/ui/Ui.java
similarity index 84%
rename from src/main/java/seedu/address/ui/Ui.java
rename to src/main/java/hirehive/address/ui/Ui.java
index 17aa0b494fe..9d946e615d3 100644
--- a/src/main/java/seedu/address/ui/Ui.java
+++ b/src/main/java/hirehive/address/ui/Ui.java
@@ -1,4 +1,4 @@
-package seedu.address.ui;
+package hirehive.address.ui;
import javafx.stage.Stage;
diff --git a/src/main/java/seedu/address/ui/UiManager.java b/src/main/java/hirehive/address/ui/UiManager.java
similarity index 93%
rename from src/main/java/seedu/address/ui/UiManager.java
rename to src/main/java/hirehive/address/ui/UiManager.java
index fdf024138bc..da1c6cdc098 100644
--- a/src/main/java/seedu/address/ui/UiManager.java
+++ b/src/main/java/hirehive/address/ui/UiManager.java
@@ -1,16 +1,16 @@
-package seedu.address.ui;
+package hirehive.address.ui;
import java.util.logging.Logger;
+import hirehive.address.MainApp;
+import hirehive.address.commons.core.LogsCenter;
+import hirehive.address.commons.util.StringUtil;
+import hirehive.address.logic.Logic;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.image.Image;
import javafx.stage.Stage;
-import seedu.address.MainApp;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.commons.util.StringUtil;
-import seedu.address.logic.Logic;
/**
* The manager of the UI component.
diff --git a/src/main/java/seedu/address/ui/UiPart.java b/src/main/java/hirehive/address/ui/UiPart.java
similarity index 97%
rename from src/main/java/seedu/address/ui/UiPart.java
rename to src/main/java/hirehive/address/ui/UiPart.java
index fc820e01a9c..76fc15a768d 100644
--- a/src/main/java/seedu/address/ui/UiPart.java
+++ b/src/main/java/hirehive/address/ui/UiPart.java
@@ -1,12 +1,12 @@
-package seedu.address.ui;
+package hirehive.address.ui;
import static java.util.Objects.requireNonNull;
import java.io.IOException;
import java.net.URL;
+import hirehive.address.MainApp;
import javafx.fxml.FXMLLoader;
-import seedu.address.MainApp;
/**
* Represents a distinct part of the UI. e.g. Windows, dialogs, panels, status bars, etc.
diff --git a/src/main/java/seedu/address/logic/Messages.java b/src/main/java/seedu/address/logic/Messages.java
deleted file mode 100644
index ecd32c31b53..00000000000
--- a/src/main/java/seedu/address/logic/Messages.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package seedu.address.logic;
-
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import seedu.address.logic.parser.Prefix;
-import seedu.address.model.person.Person;
-
-/**
- * Container for user visible messages.
- */
-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_PERSON_DISPLAYED_INDEX = "The person index provided is invalid";
- public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!";
- public static final String MESSAGE_DUPLICATE_FIELDS =
- "Multiple values specified for the following single-valued field(s): ";
-
- /**
- * Returns an error message indicating the duplicate prefixes.
- */
- public static String getErrorMessageForDuplicatePrefixes(Prefix... duplicatePrefixes) {
- assert duplicatePrefixes.length > 0;
-
- Set duplicateFields =
- Stream.of(duplicatePrefixes).map(Prefix::toString).collect(Collectors.toSet());
-
- return MESSAGE_DUPLICATE_FIELDS + String.join(" ", duplicateFields);
- }
-
- /**
- * Formats the {@code person} for display to the user.
- */
- public static String format(Person person) {
- final StringBuilder builder = new StringBuilder();
- builder.append(person.getName())
- .append("; Phone: ")
- .append(person.getPhone())
- .append("; Email: ")
- .append(person.getEmail())
- .append("; Address: ")
- .append(person.getAddress())
- .append("; Tags: ");
- person.getTags().forEach(builder::append);
- return builder.toString();
- }
-
-}
diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java
deleted file mode 100644
index 1135ac19b74..00000000000
--- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package seedu.address.logic.commands;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.List;
-
-import seedu.address.commons.core.index.Index;
-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.person.Person;
-
-/**
- * Deletes a person identified using it's displayed index from the address book.
- */
-public class DeleteCommand extends Command {
-
- public static final String COMMAND_WORD = "delete";
-
- public static final String MESSAGE_USAGE = COMMAND_WORD
- + ": Deletes the person identified by the index number used in the displayed person list.\n"
- + "Parameters: INDEX (must be a positive integer)\n"
- + "Example: " + COMMAND_WORD + " 1";
-
- public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s";
-
- private final Index targetIndex;
-
- public DeleteCommand(Index targetIndex) {
- this.targetIndex = targetIndex;
- }
-
- @Override
- public CommandResult execute(Model model) throws CommandException {
- requireNonNull(model);
- List lastShownList = model.getFilteredPersonList();
-
- if (targetIndex.getZeroBased() >= lastShownList.size()) {
- throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
- }
-
- Person personToDelete = lastShownList.get(targetIndex.getZeroBased());
- model.deletePerson(personToDelete);
- return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, Messages.format(personToDelete)));
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof DeleteCommand)) {
- return false;
- }
-
- DeleteCommand otherDeleteCommand = (DeleteCommand) other;
- return targetIndex.equals(otherDeleteCommand.targetIndex);
- }
-
- @Override
- public String toString() {
- return new ToStringBuilder(this)
- .add("targetIndex", targetIndex)
- .toString();
- }
-}
diff --git a/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java
deleted file mode 100644
index 3527fe76a3e..00000000000
--- a/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package seedu.address.logic.parser;
-
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-
-import seedu.address.commons.core.index.Index;
-import seedu.address.logic.commands.DeleteCommand;
-import seedu.address.logic.parser.exceptions.ParseException;
-
-/**
- * Parses input arguments and creates a new DeleteCommand object
- */
-public class DeleteCommandParser implements Parser {
-
- /**
- * Parses the given {@code String} of arguments in the context of the DeleteCommand
- * and returns a DeleteCommand object for execution.
- * @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 (ParseException pe) {
- throw new ParseException(
- String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE), pe);
- }
- }
-
-}
diff --git a/src/main/java/seedu/address/logic/parser/EditCommandParser.java b/src/main/java/seedu/address/logic/parser/EditCommandParser.java
deleted file mode 100644
index 46b3309a78b..00000000000
--- a/src/main/java/seedu/address/logic/parser/EditCommandParser.java
+++ /dev/null
@@ -1,85 +0,0 @@
-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_EMAIL;
-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_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.EditCommand;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.tag.Tag;
-
-/**
- * Parses input arguments and creates a new EditCommand object
- */
-public class EditCommandParser 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 EditCommand parse(String args) throws ParseException {
- requireNonNull(args);
- ArgumentMultimap argMultimap =
- ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG);
-
- Index index;
-
- try {
- index = ParserUtil.parseIndex(argMultimap.getPreamble());
- } catch (ParseException pe) {
- throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE), pe);
- }
-
- argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS);
-
- EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor();
-
- if (argMultimap.getValue(PREFIX_NAME).isPresent()) {
- editPersonDescriptor.setName(ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get()));
- }
- if (argMultimap.getValue(PREFIX_PHONE).isPresent()) {
- editPersonDescriptor.setPhone(ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get()));
- }
- if (argMultimap.getValue(PREFIX_EMAIL).isPresent()) {
- editPersonDescriptor.setEmail(ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get()));
- }
- if (argMultimap.getValue(PREFIX_ADDRESS).isPresent()) {
- editPersonDescriptor.setAddress(ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get()));
- }
- parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editPersonDescriptor::setTags);
-
- if (!editPersonDescriptor.isAnyFieldEdited()) {
- throw new ParseException(EditCommand.MESSAGE_NOT_EDITED);
- }
-
- return new EditCommand(index, editPersonDescriptor);
- }
-
- /**
- * 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/person/NameContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java
deleted file mode 100644
index 62d19be2977..00000000000
--- a/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package seedu.address.model.person;
-
-import java.util.List;
-import java.util.function.Predicate;
-
-import seedu.address.commons.util.StringUtil;
-import seedu.address.commons.util.ToStringBuilder;
-
-/**
- * Tests that a {@code Person}'s {@code Name} matches any of the keywords given.
- */
-public class NameContainsKeywordsPredicate implements Predicate {
- private final List keywords;
-
- public NameContainsKeywordsPredicate(List keywords) {
- this.keywords = keywords;
- }
-
- @Override
- public boolean test(Person person) {
- return keywords.stream()
- .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getName().fullName, keyword));
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof NameContainsKeywordsPredicate)) {
- return false;
- }
-
- NameContainsKeywordsPredicate otherNameContainsKeywordsPredicate = (NameContainsKeywordsPredicate) other;
- return keywords.equals(otherNameContainsKeywordsPredicate.keywords);
- }
-
- @Override
- public String toString() {
- return new ToStringBuilder(this).add("keywords", keywords).toString();
- }
-}
diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java
deleted file mode 100644
index abe8c46b535..00000000000
--- a/src/main/java/seedu/address/model/person/Person.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package seedu.address.model.person;
-
-import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-
-import seedu.address.commons.util.ToStringBuilder;
-import seedu.address.model.tag.Tag;
-
-/**
- * Represents a Person in the address book.
- * Guarantees: details are present and not null, field values are validated, immutable.
- */
-public class Person {
-
- // Identity fields
- private final Name name;
- private final Phone phone;
- private final Email email;
-
- // Data fields
- private final Address address;
- private final Set tags = new HashSet<>();
-
- /**
- * Every field must be present and not null.
- */
- public Person(Name name, Phone phone, Email email, Address address, Set tags) {
- requireAllNonNull(name, phone, email, address, tags);
- this.name = name;
- this.phone = phone;
- this.email = email;
- this.address = address;
- this.tags.addAll(tags);
- }
-
- public Name getName() {
- return name;
- }
-
- public Phone getPhone() {
- return phone;
- }
-
- public Email getEmail() {
- return email;
- }
-
- public Address getAddress() {
- return address;
- }
-
- /**
- * Returns an immutable tag set, which throws {@code UnsupportedOperationException}
- * if modification is attempted.
- */
- public Set getTags() {
- return Collections.unmodifiableSet(tags);
- }
-
- /**
- * Returns true if both persons have the same name.
- * This defines a weaker notion of equality between two persons.
- */
- public boolean isSamePerson(Person otherPerson) {
- if (otherPerson == this) {
- return true;
- }
-
- return otherPerson != null
- && otherPerson.getName().equals(getName());
- }
-
- /**
- * Returns true if both persons have the same identity and data fields.
- * This defines a stronger notion of equality between two persons.
- */
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof Person)) {
- return false;
- }
-
- Person otherPerson = (Person) other;
- return name.equals(otherPerson.name)
- && phone.equals(otherPerson.phone)
- && email.equals(otherPerson.email)
- && address.equals(otherPerson.address)
- && tags.equals(otherPerson.tags);
- }
-
- @Override
- public int hashCode() {
- // use this method for custom fields hashing instead of implementing your own
- return Objects.hash(name, phone, email, address, tags);
- }
-
- @Override
- public String toString() {
- return new ToStringBuilder(this)
- .add("name", name)
- .add("phone", phone)
- .add("email", email)
- .add("address", address)
- .add("tags", tags)
- .toString();
- }
-
-}
diff --git a/src/main/java/seedu/address/model/tag/Tag.java b/src/main/java/seedu/address/model/tag/Tag.java
deleted file mode 100644
index f1a0d4e233b..00000000000
--- a/src/main/java/seedu/address/model/tag/Tag.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package seedu.address.model.tag;
-
-import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.AppUtil.checkArgument;
-
-/**
- * Represents a Tag in the address book.
- * Guarantees: immutable; name is valid as declared in {@link #isValidTagName(String)}
- */
-public class Tag {
-
- public static final String MESSAGE_CONSTRAINTS = "Tags names should be alphanumeric";
- public static final String VALIDATION_REGEX = "\\p{Alnum}+";
-
- public final String tagName;
-
- /**
- * Constructs a {@code Tag}.
- *
- * @param tagName A valid tag name.
- */
- public Tag(String tagName) {
- requireNonNull(tagName);
- checkArgument(isValidTagName(tagName), MESSAGE_CONSTRAINTS);
- this.tagName = tagName;
- }
-
- /**
- * Returns true if a given string is a valid tag name.
- */
- public static boolean isValidTagName(String test) {
- return test.matches(VALIDATION_REGEX);
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof Tag)) {
- return false;
- }
-
- Tag otherTag = (Tag) other;
- return tagName.equals(otherTag.tagName);
- }
-
- @Override
- public int hashCode() {
- return tagName.hashCode();
- }
-
- /**
- * Format state as text for viewing.
- */
- public String toString() {
- return '[' + tagName + ']';
- }
-
-}
diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java
deleted file mode 100644
index 1806da4facf..00000000000
--- a/src/main/java/seedu/address/model/util/SampleDataUtil.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package seedu.address.model.util;
-
-import java.util.Arrays;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import seedu.address.model.AddressBook;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-
-/**
- * Contains utility methods for populating {@code AddressBook} with sample data.
- */
-public class SampleDataUtil {
- public static Person[] getSamplePersons() {
- return new Person[] {
- new Person(new Name("Alex Yeoh"), new Phone("87438807"), new Email("alexyeoh@example.com"),
- new Address("Blk 30 Geylang Street 29, #06-40"),
- getTagSet("friends")),
- new Person(new Name("Bernice Yu"), new Phone("99272758"), new Email("berniceyu@example.com"),
- new Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"),
- getTagSet("colleagues", "friends")),
- new Person(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Email("charlotte@example.com"),
- new Address("Blk 11 Ang Mo Kio Street 74, #11-04"),
- getTagSet("neighbours")),
- new Person(new Name("David Li"), new Phone("91031282"), new Email("lidavid@example.com"),
- new Address("Blk 436 Serangoon Gardens Street 26, #16-43"),
- getTagSet("family")),
- new Person(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"),
- new Address("Blk 47 Tampines Street 20, #17-35"),
- getTagSet("classmates")),
- new Person(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"),
- new Address("Blk 45 Aljunied Street 85, #11-31"),
- getTagSet("colleagues"))
- };
- }
-
- public static ReadOnlyAddressBook getSampleAddressBook() {
- AddressBook sampleAb = new AddressBook();
- for (Person samplePerson : getSamplePersons()) {
- sampleAb.addPerson(samplePerson);
- }
- return sampleAb;
- }
-
- /**
- * Returns a tag set containing the list of strings given.
- */
- public static Set getTagSet(String... strings) {
- return Arrays.stream(strings)
- .map(Tag::new)
- .collect(Collectors.toSet());
- }
-
-}
diff --git a/src/main/resources/images/note_icon.png b/src/main/resources/images/note_icon.png
new file mode 100644
index 00000000000..1cf8ba73635
Binary files /dev/null and b/src/main/resources/images/note_icon.png differ
diff --git a/src/main/resources/view/DarkTheme.css b/src/main/resources/view/DarkTheme.css
index 36e6b001cd8..5bd93aadc1f 100644
--- a/src/main/resources/view/DarkTheme.css
+++ b/src/main/resources/view/DarkTheme.css
@@ -146,6 +146,10 @@
-fx-background-color: derive(#1d1d1d, 30%);
}
+.status-bar-label {
+ -fx-text-fill: #FFFFFF;
+}
+
.result-display {
-fx-background-color: transparent;
-fx-font-family: "Segoe UI Light";
@@ -344,9 +348,28 @@
#tags .label {
-fx-text-fill: white;
- -fx-background-color: #3e7b91;
-fx-padding: 1 3 1 3;
-fx-border-radius: 2;
-fx-background-radius: 2;
-fx-font-size: 11;
}
+
+#tags .rejected {
+ -fx-background-color: #913F51;
+}
+
+#tags .applicant {
+ -fx-background-color: #3e7b91;
+}
+
+#tags .candidate {
+ -fx-background-color: #3C8F76;
+}
+
+#tags .interviewee {
+ -fx-background-color: #4B8F3A;
+}
+
+#tags .offered {
+ -fx-background-color: #918C3F;
+}
diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml
index 7778f666a0a..348755821f2 100644
--- a/src/main/resources/view/MainWindow.fxml
+++ b/src/main/resources/view/MainWindow.fxml
@@ -3,6 +3,7 @@
+
@@ -12,7 +13,7 @@
+ title="HireHive" minWidth="450" minHeight="600" onCloseRequest="#handleExit">
@@ -46,6 +47,13 @@
+
+
+
+
+
+
+
diff --git a/src/main/resources/view/NoteWindow.css b/src/main/resources/view/NoteWindow.css
new file mode 100644
index 00000000000..41af2d974e6
--- /dev/null
+++ b/src/main/resources/view/NoteWindow.css
@@ -0,0 +1,28 @@
+#note {
+ -fx-background-color: derive(#1d1d1d, 20%);
+ -fx-border-color: white;
+ -fx-text-fill: white;
+}
+
+#note .content {
+ -fx-background-color: derive(#1d1d1d, 20%);
+}
+
+#noteContainer {
+ -fx-background-color: derive(#1d1d1d, 20%);
+}
+
+#copy {
+ -fx-text-fill: white;
+ -fx-background-color: dimgray;
+
+}
+
+#copy:hover {
+ -fx-background-color: gray;
+}
+
+#copy:armed {
+ -fx-background-color: green;
+
+}
diff --git a/src/main/resources/view/NoteWindow.fxml b/src/main/resources/view/NoteWindow.fxml
new file mode 100644
index 00000000000..a03db00e77b
--- /dev/null
+++ b/src/main/resources/view/NoteWindow.fxml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/view/PersonListCard.fxml b/src/main/resources/view/PersonListCard.fxml
index 84e09833a87..5f59ff838eb 100644
--- a/src/main/resources/view/PersonListCard.fxml
+++ b/src/main/resources/view/PersonListCard.fxml
@@ -18,19 +18,34 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json
index a7427fe7aa2..ffa11544050 100644
--- a/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json
+++ b/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json
@@ -4,11 +4,18 @@
"phone": "94351253",
"email": "alice@example.com",
"address": "123, Jurong West Ave 6, #08-111",
- "tags": [ "friends" ]
+ "role": "Software Engineer",
+ "tag": "applicant",
+ "note" : "",
+ "date" : ""
}, {
"name": "Alice Pauline",
"phone": "94351253",
"email": "pauline@example.com",
- "address": "4th street"
+ "address": "4th street",
+ "role": "Software Engineer",
+ "tag": "applicant",
+ "note" : "Happy",
+ "date" : ""
} ]
}
diff --git a/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json
index ad3f135ae42..4ed03e8f9ae 100644
--- a/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json
+++ b/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json
@@ -3,6 +3,7 @@
"name": "Hans Muster",
"phone": "9482424",
"email": "invalid@email!3e",
- "address": "4th street"
+ "address": "4th street",
+ "role": "Software Engineer"
} ]
}
diff --git a/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json
index 72262099d35..5b30a61421f 100644
--- a/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json
+++ b/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json
@@ -5,42 +5,63 @@
"phone" : "94351253",
"email" : "alice@example.com",
"address" : "123, Jurong West Ave 6, #08-111",
- "tags" : [ "friends" ]
+ "role": "Software Engineer",
+ "tag" : "Applicant",
+ "note" : "Shy",
+ "date" : ""
}, {
"name" : "Benson Meier",
"phone" : "98765432",
"email" : "johnd@example.com",
"address" : "311, Clementi Ave 2, #02-25",
- "tags" : [ "owesMoney", "friends" ]
+ "role": "Software Engineer",
+ "tag" : "Rejected",
+ "note" : "6 foot tall",
+ "date" : "01/02/2025"
}, {
"name" : "Carl Kurz",
"phone" : "95352563",
"email" : "heinz@example.com",
"address" : "wall street",
- "tags" : [ ]
+ "role": "Software Engineer",
+ "tag" : "Interviewee",
+ "note" : "Only 18 years old",
+ "date" : "01/04/2025"
}, {
"name" : "Daniel Meier",
"phone" : "87652533",
"email" : "cornelia@example.com",
"address" : "10th street",
- "tags" : [ "friends" ]
+ "role": "Software Engineer",
+ "tag" : "Applicant",
+ "note" : "Funny",
+ "date" : ""
}, {
"name" : "Elle Meyer",
- "phone" : "9482224",
+ "phone" : "94822243",
"email" : "werner@example.com",
"address" : "michegan ave",
- "tags" : [ ]
+ "role": "Software Engineer",
+ "tag" : "Rejected",
+ "note" : "Cheerful",
+ "date" : "01/03/2025"
}, {
"name" : "Fiona Kunz",
- "phone" : "9482427",
+ "phone" : "94824273",
"email" : "lydia@example.com",
"address" : "little tokyo",
- "tags" : [ ]
+ "role": "Software Engineer",
+ "tag" : "Rejected",
+ "note" : "Scary",
+ "date" : "01/03/2025"
}, {
"name" : "George Best",
- "phone" : "9482442",
+ "phone" : "94824421",
"email" : "anna@example.com",
"address" : "4th street",
- "tags" : [ ]
+ "role": "Software Engineer",
+ "tag" : "Applicant",
+ "note" : "Fat",
+ "date" : ""
} ]
}
diff --git a/src/test/java/seedu/address/AppParametersTest.java b/src/test/java/hirehive/address/AppParametersTest.java
similarity index 99%
rename from src/test/java/seedu/address/AppParametersTest.java
rename to src/test/java/hirehive/address/AppParametersTest.java
index 133cc008bce..0a5926338f6 100644
--- a/src/test/java/seedu/address/AppParametersTest.java
+++ b/src/test/java/hirehive/address/AppParametersTest.java
@@ -1,4 +1,4 @@
-package seedu.address;
+package hirehive.address;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
diff --git a/src/test/java/hirehive/address/MainAppTest.java b/src/test/java/hirehive/address/MainAppTest.java
new file mode 100644
index 00000000000..21ef05a3c84
--- /dev/null
+++ b/src/test/java/hirehive/address/MainAppTest.java
@@ -0,0 +1,15 @@
+package hirehive.address;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.commons.core.Version;
+
+public class MainAppTest {
+ @Test
+ public void versionNumber_isCorrect() {
+ Version expectedVersion = new Version(1, 3, 0, true);
+ assertEquals(expectedVersion, MainApp.VERSION, "App version should be 1.3.0");
+ }
+}
diff --git a/src/test/java/seedu/address/commons/core/ConfigTest.java b/src/test/java/hirehive/address/commons/core/ConfigTest.java
similarity index 95%
rename from src/test/java/seedu/address/commons/core/ConfigTest.java
rename to src/test/java/hirehive/address/commons/core/ConfigTest.java
index d3ba2a52a89..7d34fa88e97 100644
--- a/src/test/java/seedu/address/commons/core/ConfigTest.java
+++ b/src/test/java/hirehive/address/commons/core/ConfigTest.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.core;
+package hirehive.address.commons.core;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
diff --git a/src/test/java/seedu/address/commons/core/GuiSettingsTest.java b/src/test/java/hirehive/address/commons/core/GuiSettingsTest.java
similarity index 93%
rename from src/test/java/seedu/address/commons/core/GuiSettingsTest.java
rename to src/test/java/hirehive/address/commons/core/GuiSettingsTest.java
index b7876c4349d..6d783166bd9 100644
--- a/src/test/java/seedu/address/commons/core/GuiSettingsTest.java
+++ b/src/test/java/hirehive/address/commons/core/GuiSettingsTest.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.core;
+package hirehive.address.commons.core;
import static org.junit.jupiter.api.Assertions.assertEquals;
diff --git a/src/test/java/seedu/address/commons/core/VersionTest.java b/src/test/java/hirehive/address/commons/core/VersionTest.java
similarity index 94%
rename from src/test/java/seedu/address/commons/core/VersionTest.java
rename to src/test/java/hirehive/address/commons/core/VersionTest.java
index 495cd231554..68bf6f411cb 100644
--- a/src/test/java/seedu/address/commons/core/VersionTest.java
+++ b/src/test/java/hirehive/address/commons/core/VersionTest.java
@@ -1,11 +1,13 @@
-package seedu.address.commons.core;
+package hirehive.address.commons.core;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
import org.junit.jupiter.api.Test;
+import hirehive.address.testutil.Assert;
+
public class VersionTest {
@Test
@@ -17,7 +19,7 @@ public void versionParsing_acceptableVersionString_parsedVersionCorrectly() {
@Test
public void versionParsing_wrongVersionString_throwIllegalArgumentException() {
- assertThrows(IllegalArgumentException.class, () -> Version.fromString("This is not a version string"));
+ Assert.assertThrows(IllegalArgumentException.class, () -> Version.fromString("This is not a version string"));
}
@Test
diff --git a/src/test/java/seedu/address/commons/core/index/IndexTest.java b/src/test/java/hirehive/address/commons/core/index/IndexTest.java
similarity index 86%
rename from src/test/java/seedu/address/commons/core/index/IndexTest.java
rename to src/test/java/hirehive/address/commons/core/index/IndexTest.java
index fc395ab964b..a7ddf9b5110 100644
--- a/src/test/java/seedu/address/commons/core/index/IndexTest.java
+++ b/src/test/java/hirehive/address/commons/core/index/IndexTest.java
@@ -1,18 +1,20 @@
-package seedu.address.commons.core.index;
+package hirehive.address.commons.core.index;
+import static hirehive.address.testutil.Assert.assertThrows;
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.testutil.Assert.assertThrows;
import org.junit.jupiter.api.Test;
+import hirehive.address.testutil.Assert;
+
public class IndexTest {
@Test
public void createOneBasedIndex() {
// invalid index
- assertThrows(IndexOutOfBoundsException.class, () -> Index.fromOneBased(0));
+ Assert.assertThrows(IndexOutOfBoundsException.class, () -> Index.fromOneBased(0));
// check equality using the same base
assertEquals(1, Index.fromOneBased(1).getOneBased());
@@ -26,7 +28,7 @@ public void createOneBasedIndex() {
@Test
public void createZeroBasedIndex() {
// invalid index
- assertThrows(IndexOutOfBoundsException.class, () -> Index.fromZeroBased(-1));
+ Assert.assertThrows(IndexOutOfBoundsException.class, () -> Index.fromZeroBased(-1));
// check equality using the same base
assertEquals(0, Index.fromZeroBased(0).getZeroBased());
diff --git a/src/test/java/seedu/address/commons/util/AppUtilTest.java b/src/test/java/hirehive/address/commons/util/AppUtilTest.java
similarity index 62%
rename from src/test/java/seedu/address/commons/util/AppUtilTest.java
rename to src/test/java/hirehive/address/commons/util/AppUtilTest.java
index 594de1e6365..74cbb322906 100644
--- a/src/test/java/seedu/address/commons/util/AppUtilTest.java
+++ b/src/test/java/hirehive/address/commons/util/AppUtilTest.java
@@ -1,10 +1,12 @@
-package seedu.address.commons.util;
+package hirehive.address.commons.util;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static seedu.address.testutil.Assert.assertThrows;
import org.junit.jupiter.api.Test;
+import hirehive.address.testutil.Assert;
+
public class AppUtilTest {
@Test
@@ -14,7 +16,7 @@ public void getImage_exitingImage() {
@Test
public void getImage_nullGiven_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> AppUtil.getImage(null));
+ Assert.assertThrows(NullPointerException.class, () -> AppUtil.getImage(null));
}
@Test
@@ -25,12 +27,12 @@ public void checkArgument_true_nothingHappens() {
@Test
public void checkArgument_falseWithoutErrorMessage_throwsIllegalArgumentException() {
- assertThrows(IllegalArgumentException.class, () -> AppUtil.checkArgument(false));
+ Assert.assertThrows(IllegalArgumentException.class, () -> AppUtil.checkArgument(false));
}
@Test
public void checkArgument_falseWithErrorMessage_throwsIllegalArgumentException() {
String errorMessage = "error message";
- assertThrows(IllegalArgumentException.class, errorMessage, () -> AppUtil.checkArgument(false, errorMessage));
+ Assert.assertThrows(IllegalArgumentException.class, errorMessage, () -> AppUtil.checkArgument(false, errorMessage));
}
}
diff --git a/src/test/java/seedu/address/commons/util/CollectionUtilTest.java b/src/test/java/hirehive/address/commons/util/CollectionUtilTest.java
similarity index 88%
rename from src/test/java/seedu/address/commons/util/CollectionUtilTest.java
rename to src/test/java/hirehive/address/commons/util/CollectionUtilTest.java
index b467a3dc025..08ec98a74dc 100644
--- a/src/test/java/seedu/address/commons/util/CollectionUtilTest.java
+++ b/src/test/java/hirehive/address/commons/util/CollectionUtilTest.java
@@ -1,9 +1,9 @@
-package seedu.address.commons.util;
+package hirehive.address.commons.util;
+import static hirehive.address.commons.util.CollectionUtil.requireAllNonNull;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
-import static seedu.address.testutil.Assert.assertThrows;
import java.util.Arrays;
import java.util.Collection;
@@ -12,6 +12,8 @@
import org.junit.jupiter.api.Test;
+import hirehive.address.testutil.Assert;
+
public class CollectionUtilTest {
@Test
public void requireAllNonNullVarargs() {
@@ -87,7 +89,7 @@ public void isAnyNonNull() {
* if {@code objects} or any element of {@code objects} is null.
*/
private void assertNullPointerExceptionThrown(Object... objects) {
- assertThrows(NullPointerException.class, () -> requireAllNonNull(objects));
+ Assert.assertThrows(NullPointerException.class, () -> CollectionUtil.requireAllNonNull(objects));
}
/**
@@ -95,14 +97,14 @@ private void assertNullPointerExceptionThrown(Object... objects) {
* if {@code collection} or any element of {@code collection} is null.
*/
private void assertNullPointerExceptionThrown(Collection> collection) {
- assertThrows(NullPointerException.class, () -> requireAllNonNull(collection));
+ Assert.assertThrows(NullPointerException.class, () -> CollectionUtil.requireAllNonNull(collection));
}
private void assertNullPointerExceptionNotThrown(Object... objects) {
- requireAllNonNull(objects);
+ CollectionUtil.requireAllNonNull(objects);
}
private void assertNullPointerExceptionNotThrown(Collection> collection) {
- requireAllNonNull(collection);
+ CollectionUtil.requireAllNonNull(collection);
}
}
diff --git a/src/test/java/seedu/address/commons/util/ConfigUtilTest.java b/src/test/java/hirehive/address/commons/util/ConfigUtilTest.java
similarity index 84%
rename from src/test/java/seedu/address/commons/util/ConfigUtilTest.java
rename to src/test/java/hirehive/address/commons/util/ConfigUtilTest.java
index 69d7b89cfd8..5a97343f88a 100644
--- a/src/test/java/seedu/address/commons/util/ConfigUtilTest.java
+++ b/src/test/java/hirehive/address/commons/util/ConfigUtilTest.java
@@ -1,8 +1,8 @@
-package seedu.address.commons.util;
+package hirehive.address.commons.util;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
-import static seedu.address.testutil.Assert.assertThrows;
import java.io.IOException;
import java.nio.file.Path;
@@ -13,8 +13,9 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
-import seedu.address.commons.core.Config;
-import seedu.address.commons.exceptions.DataLoadingException;
+import hirehive.address.commons.core.Config;
+import hirehive.address.commons.exceptions.DataLoadingException;
+import hirehive.address.testutil.Assert;
public class ConfigUtilTest {
@@ -25,7 +26,7 @@ public class ConfigUtilTest {
@Test
public void read_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> read(null));
+ Assert.assertThrows(NullPointerException.class, () -> read(null));
}
@Test
@@ -35,7 +36,7 @@ public void read_missingFile_emptyResult() throws DataLoadingException {
@Test
public void read_notJsonFormat_exceptionThrown() {
- assertThrows(DataLoadingException.class, () -> read("NotJsonFormatConfig.json"));
+ Assert.assertThrows(DataLoadingException.class, () -> read("NotJsonFormatConfig.json"));
}
@Test
@@ -75,12 +76,12 @@ private Optional read(String configFileInTestDataFolder) throws DataLoad
@Test
public void save_nullConfig_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> save(null, "SomeFile.json"));
+ Assert.assertThrows(NullPointerException.class, () -> save(null, "SomeFile.json"));
}
@Test
public void save_nullFile_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> save(new Config(), null));
+ Assert.assertThrows(NullPointerException.class, () -> save(new Config(), null));
}
@Test
diff --git a/src/test/java/seedu/address/commons/util/FileUtilTest.java b/src/test/java/hirehive/address/commons/util/FileUtilTest.java
similarity index 65%
rename from src/test/java/seedu/address/commons/util/FileUtilTest.java
rename to src/test/java/hirehive/address/commons/util/FileUtilTest.java
index 1fe5478c756..a29520ed051 100644
--- a/src/test/java/seedu/address/commons/util/FileUtilTest.java
+++ b/src/test/java/hirehive/address/commons/util/FileUtilTest.java
@@ -1,11 +1,13 @@
-package seedu.address.commons.util;
+package hirehive.address.commons.util;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
import org.junit.jupiter.api.Test;
+import hirehive.address.testutil.Assert;
+
public class FileUtilTest {
@Test
@@ -17,7 +19,7 @@ public void isValidPath() {
assertFalse(FileUtil.isValidPath("a\0"));
// null path -> throws NullPointerException
- assertThrows(NullPointerException.class, () -> FileUtil.isValidPath(null));
+ Assert.assertThrows(NullPointerException.class, () -> FileUtil.isValidPath(null));
}
}
diff --git a/src/test/java/seedu/address/commons/util/JsonUtilTest.java b/src/test/java/hirehive/address/commons/util/JsonUtilTest.java
similarity index 92%
rename from src/test/java/seedu/address/commons/util/JsonUtilTest.java
rename to src/test/java/hirehive/address/commons/util/JsonUtilTest.java
index d4907539dee..12708a88566 100644
--- a/src/test/java/seedu/address/commons/util/JsonUtilTest.java
+++ b/src/test/java/hirehive/address/commons/util/JsonUtilTest.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.util;
+package hirehive.address.commons.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -7,8 +7,8 @@
import org.junit.jupiter.api.Test;
-import seedu.address.testutil.SerializableTestClass;
-import seedu.address.testutil.TestUtil;
+import hirehive.address.testutil.SerializableTestClass;
+import hirehive.address.testutil.TestUtil;
/**
* Tests JSON Read and Write
diff --git a/src/test/java/seedu/address/commons/util/StringUtilTest.java b/src/test/java/hirehive/address/commons/util/StringUtilTest.java
similarity index 70%
rename from src/test/java/seedu/address/commons/util/StringUtilTest.java
rename to src/test/java/hirehive/address/commons/util/StringUtilTest.java
index c56d407bf3f..5f09566049c 100644
--- a/src/test/java/seedu/address/commons/util/StringUtilTest.java
+++ b/src/test/java/hirehive/address/commons/util/StringUtilTest.java
@@ -1,13 +1,15 @@
-package seedu.address.commons.util;
+package hirehive.address.commons.util;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
import java.io.FileNotFoundException;
import org.junit.jupiter.api.Test;
+import hirehive.address.testutil.Assert;
+
public class StringUtilTest {
//---------------- Tests for isNonZeroUnsignedInteger --------------------------------------
@@ -45,6 +47,42 @@ public void isNonZeroUnsignedInteger() {
assertTrue(StringUtil.isNonZeroUnsignedInteger("10"));
}
+ @Test
+ public void isPositiveInteger() {
+ // EP: empty strings
+ assertFalse(StringUtil.isPositiveInteger("")); // Boundary value
+ assertFalse(StringUtil.isPositiveInteger(" "));
+
+ // EP: not a number
+ assertFalse(StringUtil.isPositiveInteger("a"));
+ assertFalse(StringUtil.isPositiveInteger("aaa"));
+
+ // EP: zero as prefix
+ assertTrue(StringUtil.isPositiveInteger("01"));
+
+ // EP: signed numbers
+ assertFalse(StringUtil.isPositiveInteger("-1"));
+ assertFalse(StringUtil.isPositiveInteger("+1"));
+
+ // EP: numbers with white space
+ assertFalse(StringUtil.isPositiveInteger(" 10 ")); // Leading/trailing spaces
+ assertFalse(StringUtil.isPositiveInteger("1 0")); // Spaces in the middle
+
+ // EP: number larger than Integer.MAX_VALUE
+ assertFalse(StringUtil.isPositiveInteger(Long.toString(Integer.MAX_VALUE + 1)));
+
+ // EP: valid numbers, should return true
+ assertTrue(StringUtil.isPositiveInteger("0"));
+ assertTrue(StringUtil.isPositiveInteger("10"));
+ }
+
+ @Test
+ public void isValidStringOrInteger() {
+ assertTrue(StringUtil.isValidStringOrInteger("aaaaa"));
+ assertTrue(StringUtil.isValidStringOrInteger("2147483647"));
+ assertFalse(StringUtil.isValidStringOrInteger("2147483648"));
+ }
+
//---------------- Tests for containsWordIgnoreCase --------------------------------------
@@ -56,24 +94,18 @@ public void isNonZeroUnsignedInteger() {
@Test
public void containsWordIgnoreCase_nullWord_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> StringUtil.containsWordIgnoreCase("typical sentence", null));
+ Assert.assertThrows(NullPointerException.class, () -> StringUtil.containsWordIgnoreCase("typical sentence", null));
}
@Test
public void containsWordIgnoreCase_emptyWord_throwsIllegalArgumentException() {
- assertThrows(IllegalArgumentException.class, "Word parameter cannot be empty", ()
+ Assert.assertThrows(IllegalArgumentException.class, "Word parameter cannot be empty", ()
-> StringUtil.containsWordIgnoreCase("typical sentence", " "));
}
- @Test
- public void containsWordIgnoreCase_multipleWords_throwsIllegalArgumentException() {
- assertThrows(IllegalArgumentException.class, "Word parameter should be a single word", ()
- -> StringUtil.containsWordIgnoreCase("typical sentence", "aaa BBB"));
- }
-
@Test
public void containsWordIgnoreCase_nullSentence_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> StringUtil.containsWordIgnoreCase(null, "abc"));
+ Assert.assertThrows(NullPointerException.class, () -> StringUtil.containsWordIgnoreCase(null, "abc"));
}
/*
@@ -109,7 +141,7 @@ public void containsWordIgnoreCase_validInputs_correctResult() {
assertFalse(StringUtil.containsWordIgnoreCase(" ", "123"));
// Matches a partial word only
- assertFalse(StringUtil.containsWordIgnoreCase("aaa bbb ccc", "bb")); // Sentence word bigger than query word
+ assertTrue(StringUtil.containsWordIgnoreCase("aaa bbb ccc", "bb")); // Sentence word bigger than query word
assertFalse(StringUtil.containsWordIgnoreCase("aaa bbb ccc", "bbbb")); // Query word bigger than sentence word
// Matches word in the sentence, different upper/lower case letters
@@ -137,7 +169,7 @@ public void getDetails_exceptionGiven() {
@Test
public void getDetails_nullGiven_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> StringUtil.getDetails(null));
+ Assert.assertThrows(NullPointerException.class, () -> StringUtil.getDetails(null));
}
}
diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/hirehive/address/logic/LogicManagerTest.java
similarity index 72%
rename from src/test/java/seedu/address/logic/LogicManagerTest.java
rename to src/test/java/hirehive/address/logic/LogicManagerTest.java
index baf8ce336a2..daf4f872bc0 100644
--- a/src/test/java/seedu/address/logic/LogicManagerTest.java
+++ b/src/test/java/hirehive/address/logic/LogicManagerTest.java
@@ -1,14 +1,8 @@
-package seedu.address.logic;
+package hirehive.address.logic;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static seedu.address.logic.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX;
-import static seedu.address.logic.Messages.MESSAGE_UNKNOWN_COMMAND;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_AMY;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.AMY;
+import static org.junit.jupiter.api.Assertions.assertNull;
import java.io.IOException;
import java.nio.file.AccessDeniedException;
@@ -18,20 +12,24 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
-import seedu.address.logic.commands.AddCommand;
-import seedu.address.logic.commands.CommandResult;
-import seedu.address.logic.commands.ListCommand;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.UserPrefs;
-import seedu.address.model.person.Person;
-import seedu.address.storage.JsonAddressBookStorage;
-import seedu.address.storage.JsonUserPrefsStorage;
-import seedu.address.storage.StorageManager;
-import seedu.address.testutil.PersonBuilder;
+import hirehive.address.logic.commands.AddCommand;
+import hirehive.address.logic.commands.CommandResult;
+import hirehive.address.logic.commands.CommandTestUtil;
+import hirehive.address.logic.commands.ListCommand;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.ReadOnlyAddressBook;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
+import hirehive.address.storage.JsonAddressBookStorage;
+import hirehive.address.storage.JsonUserPrefsStorage;
+import hirehive.address.storage.StorageManager;
+import hirehive.address.testutil.Assert;
+import hirehive.address.testutil.PersonBuilder;
+import hirehive.address.testutil.TypicalPersons;
public class LogicManagerTest {
private static final IOException DUMMY_IO_EXCEPTION = new IOException("dummy IO exception");
@@ -55,13 +53,13 @@ public void setUp() {
@Test
public void execute_invalidCommandFormat_throwsParseException() {
String invalidCommand = "uicfhmowqewca";
- assertParseException(invalidCommand, MESSAGE_UNKNOWN_COMMAND);
+ assertParseException(invalidCommand, Messages.MESSAGE_UNKNOWN_COMMAND);
}
@Test
public void execute_commandExecutionError_throwsCommandException() {
- String deleteCommand = "delete 9";
- assertCommandException(deleteCommand, MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
+ String deleteCommand = "delete n/none";
+ assertCommandException(deleteCommand, Messages.MESSAGE_NO_SUCH_PERSON);
}
@Test
@@ -84,7 +82,24 @@ public void execute_storageThrowsAdException_throwsCommandException() {
@Test
public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException() {
- assertThrows(UnsupportedOperationException.class, () -> logic.getFilteredPersonList().remove(0));
+ Assert.assertThrows(UnsupportedOperationException.class, () -> logic.getFilteredPersonList().remove(0));
+ }
+
+ @Test
+ public void getPersonNote_initial_returnsDefaultNote() {
+ assertEquals(logic.getPersonNote(), new Note(Note.DEFAULT_NOTE));
+ }
+
+ @Test
+ public void getPersonNote_person_getPersonNote() {
+ model.updatePersonNote(TypicalPersons.ALICE);
+ assertEquals(logic.getPersonNote(), TypicalPersons.ALICE.getNote());
+ }
+
+ @Test
+ public void getFilteredPersonListSize_initialList_returnListSize() {
+ int listSize = model.getFilteredPersonList().size();
+ assertEquals(listSize, logic.getFilteredPersonListSize());
}
/**
@@ -136,7 +151,7 @@ private void assertCommandFailure(String inputCommand, Class extends Throwable
*/
private void assertCommandFailure(String inputCommand, Class extends Throwable> expectedException,
String expectedMessage, Model expectedModel) {
- assertThrows(expectedException, expectedMessage, () -> logic.execute(inputCommand));
+ Assert.assertThrows(expectedException, expectedMessage, () -> logic.execute(inputCommand));
assertEquals(expectedModel, model);
}
@@ -165,9 +180,9 @@ public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath)
logic = new LogicManager(model, storage);
// Triggers the saveAddressBook method by executing an add command
- String addCommand = AddCommand.COMMAND_WORD + NAME_DESC_AMY + PHONE_DESC_AMY
- + EMAIL_DESC_AMY + ADDRESS_DESC_AMY;
- Person expectedPerson = new PersonBuilder(AMY).withTags().build();
+ String addCommand = AddCommand.COMMAND_WORD + CommandTestUtil.NAME_DESC_BOB + CommandTestUtil.PHONE_DESC_BOB
+ + CommandTestUtil.EMAIL_DESC_BOB + CommandTestUtil.ADDRESS_DESC_BOB + CommandTestUtil.ROLE_DESC_BOB;
+ Person expectedPerson = new PersonBuilder(TypicalPersons.BOB).build();
ModelManager expectedModel = new ModelManager();
expectedModel.addPerson(expectedPerson);
assertCommandFailure(addCommand, CommandException.class, expectedMessage, expectedModel);
diff --git a/src/test/java/hirehive/address/logic/commands/AddCommandIntegrationTest.java b/src/test/java/hirehive/address/logic/commands/AddCommandIntegrationTest.java
new file mode 100644
index 00000000000..f5e994f96f7
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/commands/AddCommandIntegrationTest.java
@@ -0,0 +1,47 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.model.person.Person;
+import hirehive.address.testutil.PersonBuilder;
+import hirehive.address.testutil.TypicalPersons;
+
+/**
+ * Contains integration tests (interaction with the Model) for {@code AddCommand}.
+ */
+public class AddCommandIntegrationTest {
+
+ private Model model;
+
+ @BeforeEach
+ public void setUp() {
+ model = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+ }
+
+ @Test
+ public void execute_newPerson_success() {
+ Person validPerson = new PersonBuilder().build();
+
+ Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ expectedModel.addPerson(validPerson);
+
+ CommandTestUtil.assertCommandSuccess(new AddCommand(validPerson), model,
+ new CommandResult(String.format(AddCommand.MESSAGE_SUCCESS, Messages.format(validPerson)), true),
+ expectedModel);
+ }
+
+ @Test
+ public void execute_duplicatePerson_throwsCommandException() {
+ Person personInList = model.getAddressBook().getPersonList().get(0);
+ CommandTestUtil.assertCommandFailure(new AddCommand(personInList), model,
+ AddCommand.MESSAGE_DUPLICATE_PERSON);
+ }
+
+}
diff --git a/src/test/java/seedu/address/logic/commands/AddCommandTest.java b/src/test/java/hirehive/address/logic/commands/AddCommandTest.java
similarity index 74%
rename from src/test/java/seedu/address/logic/commands/AddCommandTest.java
rename to src/test/java/hirehive/address/logic/commands/AddCommandTest.java
index 90e8253f48e..c7e8bfb5d53 100644
--- a/src/test/java/seedu/address/logic/commands/AddCommandTest.java
+++ b/src/test/java/hirehive/address/logic/commands/AddCommandTest.java
@@ -1,11 +1,10 @@
-package seedu.address.logic.commands;
+package hirehive.address.logic.commands;
+import static hirehive.address.testutil.Assert.assertThrows;
import static java.util.Objects.requireNonNull;
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.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -14,22 +13,26 @@
import org.junit.jupiter.api.Test;
+import hirehive.address.commons.core.GuiSettings;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.Model;
+import hirehive.address.model.ReadOnlyAddressBook;
+import hirehive.address.model.ReadOnlyUserPrefs;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
+import hirehive.address.testutil.Assert;
+import hirehive.address.testutil.PersonBuilder;
+import hirehive.address.testutil.TypicalPersons;
import javafx.collections.ObservableList;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.logic.Messages;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.model.AddressBook;
-import seedu.address.model.Model;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.ReadOnlyUserPrefs;
-import seedu.address.model.person.Person;
-import seedu.address.testutil.PersonBuilder;
public class AddCommandTest {
@Test
public void constructor_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> new AddCommand(null));
+ Assert.assertThrows(NullPointerException.class, () -> new AddCommand(null));
}
@Test
@@ -50,7 +53,7 @@ public void execute_duplicatePerson_throwsCommandException() {
AddCommand addCommand = new AddCommand(validPerson);
ModelStub modelStub = new ModelStubWithPerson(validPerson);
- assertThrows(CommandException.class, AddCommand.MESSAGE_DUPLICATE_PERSON, () -> addCommand.execute(modelStub));
+ Assert.assertThrows(CommandException.class, AddCommand.MESSAGE_DUPLICATE_PERSON, () -> addCommand.execute(modelStub));
}
@Test
@@ -79,8 +82,8 @@ public void equals() {
@Test
public void toStringMethod() {
- AddCommand addCommand = new AddCommand(ALICE);
- String expected = AddCommand.class.getCanonicalName() + "{toAdd=" + ALICE + "}";
+ AddCommand addCommand = new AddCommand(TypicalPersons.ALICE);
+ String expected = AddCommand.class.getCanonicalName() + "{toAdd=" + TypicalPersons.ALICE + "}";
assertEquals(expected, addCommand.toString());
}
@@ -157,6 +160,41 @@ public ObservableList getFilteredPersonList() {
public void updateFilteredPersonList(Predicate predicate) {
throw new AssertionError("This method should not be called.");
}
+
+ @Override
+ public void unfilterPersonList() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void sortPersons() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void resetSorting() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void updatePersonNote(Person person) {
+ throw new AssertionError("This method should not be called");
+ }
+
+ @Override
+ public Note getPersonNote() {
+ throw new AssertionError("This method should not be called");
+ }
+
+ @Override
+ public int getListSize() {
+ throw new AssertionError("This method should not be called");
+ }
+
+ @Override
+ public InterviewDate getAvailableDate() {
+ throw new AssertionError("This method should not be called");
+ }
}
/**
diff --git a/src/test/java/hirehive/address/logic/commands/ClearCommandTest.java b/src/test/java/hirehive/address/logic/commands/ClearCommandTest.java
new file mode 100644
index 00000000000..320fe43c3ec
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/commands/ClearCommandTest.java
@@ -0,0 +1,34 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.testutil.TypicalPersons;
+
+public class ClearCommandTest {
+
+ @Test
+ public void execute_emptyAddressBook_success() {
+ Model model = new ModelManager();
+ Model expectedModel = new ModelManager();
+
+ CommandTestUtil.assertCommandSuccess(new ClearCommand(), model,
+ new CommandResult(ClearCommand.MESSAGE_SUCCESS, true), expectedModel);
+ }
+
+ @Test
+ public void execute_nonEmptyAddressBook_success() {
+ Model model = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+ Model expectedModel = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+ expectedModel.setAddressBook(new AddressBook());
+
+ CommandTestUtil.assertCommandSuccess(new ClearCommand(), model,
+ new CommandResult(ClearCommand.MESSAGE_SUCCESS, true), expectedModel);
+ }
+
+}
diff --git a/src/test/java/seedu/address/logic/commands/CommandResultTest.java b/src/test/java/hirehive/address/logic/commands/CommandResultTest.java
similarity index 60%
rename from src/test/java/seedu/address/logic/commands/CommandResultTest.java
rename to src/test/java/hirehive/address/logic/commands/CommandResultTest.java
index 7b8c7cd4546..c4f8f872d52 100644
--- a/src/test/java/seedu/address/logic/commands/CommandResultTest.java
+++ b/src/test/java/hirehive/address/logic/commands/CommandResultTest.java
@@ -1,4 +1,4 @@
-package seedu.address.logic.commands;
+package hirehive.address.logic.commands;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -14,7 +14,8 @@ public void equals() {
// same values -> returns true
assertTrue(commandResult.equals(new CommandResult("feedback")));
- assertTrue(commandResult.equals(new CommandResult("feedback", false, false)));
+ assertTrue(commandResult.equals(new CommandResult("feedback", false)));
+ assertTrue(commandResult.equals(new CommandResult("feedback", false, false, false, false)));
// same object -> returns true
assertTrue(commandResult.equals(commandResult));
@@ -28,11 +29,14 @@ public void equals() {
// different feedbackToUser value -> returns false
assertFalse(commandResult.equals(new CommandResult("different")));
+ // different isChange value -> returns false
+ assertFalse(commandResult.equals(new CommandResult("feedback", true)));
+
// different showHelp value -> returns false
- assertFalse(commandResult.equals(new CommandResult("feedback", true, false)));
+ assertFalse(commandResult.equals(new CommandResult("feedback", true, false, false, false)));
// different exit value -> returns false
- assertFalse(commandResult.equals(new CommandResult("feedback", false, true)));
+ assertFalse(commandResult.equals(new CommandResult("feedback", false, true, false, false)));
}
@Test
@@ -45,11 +49,14 @@ public void hashcode() {
// different feedbackToUser value -> returns different hashcode
assertNotEquals(commandResult.hashCode(), new CommandResult("different").hashCode());
+ // different isChange value -> returns differet hashcode
+ assertNotEquals(commandResult.hashCode(), new CommandResult("feedback", true));
+
// different showHelp value -> returns different hashcode
- assertNotEquals(commandResult.hashCode(), new CommandResult("feedback", true, false).hashCode());
+ assertNotEquals(commandResult.hashCode(), new CommandResult("feedback", true, false, false, false).hashCode());
// different exit value -> returns different hashcode
- assertNotEquals(commandResult.hashCode(), new CommandResult("feedback", false, true).hashCode());
+ assertNotEquals(commandResult.hashCode(), new CommandResult("feedback", false, true, false, false).hashCode());
}
@Test
@@ -57,7 +64,29 @@ public void toStringMethod() {
CommandResult commandResult = new CommandResult("feedback");
String expected = CommandResult.class.getCanonicalName() + "{feedbackToUser="
+ commandResult.getFeedbackToUser() + ", showHelp=" + commandResult.isShowHelp()
- + ", exit=" + commandResult.isExit() + "}";
+ + ", exit=" + commandResult.isExit() + ", showNote=" + commandResult.isShowNote()
+ + ", isChange=" + commandResult.isChange() + "}";
assertEquals(expected, commandResult.toString());
}
+
+ @Test
+ public void isShowNote() {
+ CommandResult commandResult1 = new CommandResult("feedback", false, false, true, false);
+ CommandResult commandResult2 = new CommandResult("feedback");
+ assertTrue(commandResult1.isShowNote());
+ assertFalse(commandResult2.isShowNote());
+ }
+
+ @Test
+ public void isChange() {
+ CommandResult commandResult1 = new CommandResult("feedback");
+ CommandResult commandResult2 = new CommandResult("feedback", true);
+
+ // true isChange command result -> return true
+ assertFalse(commandResult1.isChange());
+
+ // false isChange command result -> return false
+ assertTrue(commandResult2.isChange());
+ }
+
}
diff --git a/src/test/java/hirehive/address/logic/commands/CommandTestUtil.java b/src/test/java/hirehive/address/logic/commands/CommandTestUtil.java
new file mode 100644
index 00000000000..9ede0cdf7af
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/commands/CommandTestUtil.java
@@ -0,0 +1,145 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.testutil.Assert.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.parser.CliSyntax;
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.model.person.Person;
+import hirehive.address.testutil.Assert;
+import hirehive.address.testutil.EditPersonDescriptorBuilder;
+
+/**
+ * Contains helper methods for testing commands.
+ */
+public class CommandTestUtil {
+
+ public static final String VALID_NAME_AMY = "Amy Bee";
+ public static final String VALID_NAME_BOB = "Bob Choo";
+ public static final String VALID_PHONE_AMY = "91224567";
+ public static final String VALID_PHONE_BOB = "87664321";
+ public static final String VALID_EMAIL_AMY = "amy@example.com";
+ public static final String VALID_EMAIL_BOB = "bob@example.com";
+ public static final String VALID_ADDRESS_AMY = "Block 312, Amy Street 1";
+ public static final String VALID_ADDRESS_BOB = "Block 123, Bobby Street 3";
+ public static final String VALID_ROLE_AMY = "Software engineer";
+ public static final String VALID_ROLE_BOB = "Cybersecurity specialist";
+ public static final String VALID_TAG_CANDIDATE = "candidate";
+ public static final String VALID_TAG_APPLICANT = "applicant";
+ public static final String DEFAULT_TAG_APPLICANT = "Applicant";
+ public static final String VALID_NOTE_AMY = "30 years old";
+ public static final String VALID_NOTE_BOB = "";
+ public static final String VALID_DATE_BOB = "01/01/2025";
+
+ public static final String NAME_DESC_AMY = " " + CliSyntax.PREFIX_NAME + VALID_NAME_AMY;
+ public static final String NAME_DESC_BOB = " " + CliSyntax.PREFIX_NAME + VALID_NAME_BOB;
+ public static final String PHONE_DESC_AMY = " " + CliSyntax.PREFIX_PHONE + VALID_PHONE_AMY;
+ public static final String PHONE_DESC_BOB = " " + CliSyntax.PREFIX_PHONE + VALID_PHONE_BOB;
+ public static final String EMAIL_DESC_AMY = " " + CliSyntax.PREFIX_EMAIL + VALID_EMAIL_AMY;
+ public static final String EMAIL_DESC_BOB = " " + CliSyntax.PREFIX_EMAIL + VALID_EMAIL_BOB;
+ public static final String ADDRESS_DESC_AMY = " " + CliSyntax.PREFIX_ADDRESS + VALID_ADDRESS_AMY;
+ public static final String ADDRESS_DESC_BOB = " " + CliSyntax.PREFIX_ADDRESS + VALID_ADDRESS_BOB;
+ public static final String ROLE_DESC_AMY = " " + CliSyntax.PREFIX_ROLE + VALID_ROLE_AMY;
+ public static final String ROLE_DESC_BOB = " " + CliSyntax.PREFIX_ROLE + VALID_ROLE_BOB;
+ public static final String TAG_DESC_APPLICANT = " " + CliSyntax.PREFIX_TAG + VALID_TAG_APPLICANT;
+ public static final String TAG_DESC_CANDIDATE = " " + CliSyntax.PREFIX_TAG + VALID_TAG_CANDIDATE;
+ public static final String NOTE_DESC_AMY = " " + CliSyntax.PREFIX_NOTE + VALID_NOTE_AMY;
+ public static final String NOTE_DESC_BOB = " " + CliSyntax.PREFIX_NOTE + VALID_NOTE_BOB;
+
+ public static final String DATE_DESC_BOB = " " + CliSyntax.PREFIX_DATE + VALID_DATE_BOB;
+
+ public static final String INVALID_NAME_DESC = " " + CliSyntax.PREFIX_NAME + "James&"; // '&' not allowed in names
+ public static final String INVALID_PHONE_DESC = " " + CliSyntax.PREFIX_PHONE + "911a"; // 'a' not allowed in phones
+ public static final String INVALID_EMAIL_DESC = " " + CliSyntax.PREFIX_EMAIL + "bob!yahoo"; // missing '@' symbol
+ public static final String INVALID_ADDRESS_DESC = " " + CliSyntax.PREFIX_ADDRESS; // empty string not allowed for addresses
+ public static final String INVALID_ROLE_DESC = " " + CliSyntax.PREFIX_ROLE + "Developer&"; // '&' not allowed in names
+ public static final String INVALID_TAG_DESC = " " + CliSyntax.PREFIX_TAG + "hubby*"; // '*' not allowed in tags
+ public static final String INVALID_NOTE_DESC = " " + CliSyntax.PREFIX_NOTE + "Lorem ipsum dolor sit amet, "
+ + "consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque "
+ + "penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, "
+ + "pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, "
+ + "aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. "
+ + "Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus"; // >500 chars not allowed for notes
+ public static final String INVALID_DATE_DESC = " " + CliSyntax.PREFIX_DATE + "01012025";
+ public static final String PREAMBLE_WHITESPACE = "\t \r \n";
+ public static final String PREAMBLE_NON_EMPTY = "NonEmptyPreamble";
+
+ public static final EditCommand.EditPersonDescriptor DESC_AMY;
+ public static final EditCommand.EditPersonDescriptor DESC_BOB;
+
+ static {
+ DESC_AMY = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY)
+ .withPhone(VALID_PHONE_AMY).withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY)
+ .withRole(VALID_ROLE_AMY).withTag(VALID_TAG_APPLICANT).withNote(VALID_NOTE_AMY).build();
+ DESC_BOB = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB)
+ .withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB)
+ .withRole(VALID_ROLE_BOB).withTag(VALID_TAG_CANDIDATE)
+ .withNote(VALID_NOTE_BOB).build();
+ }
+
+ /**
+ * Executes the given {@code command}, confirms that
+ * - the returned {@link CommandResult} matches {@code expectedCommandResult}
+ * - the {@code actualModel} matches {@code expectedModel}
+ */
+ public static void assertCommandSuccess(Command command, Model actualModel, CommandResult expectedCommandResult,
+ Model expectedModel) {
+ try {
+ CommandResult result = command.execute(actualModel);
+ assertEquals(expectedCommandResult, result);
+ assertEquals(expectedModel, actualModel);
+ } catch (CommandException ce) {
+ throw new AssertionError("Execution of command should not fail.", ce);
+ }
+ }
+
+ /**
+ * Convenience wrapper to {@link #assertCommandSuccess(Command, Model, CommandResult, Model)}
+ * that takes a string {@code expectedMessage}.
+ */
+ public static void assertCommandSuccess(Command command, Model actualModel, String expectedMessage,
+ Model expectedModel) {
+ CommandResult expectedCommandResult = new CommandResult(expectedMessage);
+ assertCommandSuccess(command, actualModel, expectedCommandResult, expectedModel);
+ }
+
+ /**
+ * Executes the given {@code command}, confirms that
+ * - a {@code CommandException} is thrown
+ * - the CommandException message matches {@code expectedMessage}
+ * - the address book, filtered person list and selected person in {@code actualModel} remain unchanged
+ */
+ public static void assertCommandFailure(Command command, Model actualModel, String expectedMessage) {
+ // we are unable to defensively copy the model for comparison later, so we can
+ // only do so by copying its components.
+ AddressBook expectedAddressBook = new AddressBook(actualModel.getAddressBook());
+ List expectedFilteredList = new ArrayList<>(actualModel.getFilteredPersonList());
+
+ Assert.assertThrows(CommandException.class, expectedMessage, () -> command.execute(actualModel));
+ assertEquals(expectedAddressBook, actualModel.getAddressBook());
+ assertEquals(expectedFilteredList, actualModel.getFilteredPersonList());
+ }
+ /**
+ * Updates {@code model}'s filtered list to show only the person at the given {@code targetIndex} in the
+ * {@code model}'s address book.
+ */
+ public static void showPersonAtIndex(Model model, Index targetIndex) {
+ assertTrue(targetIndex.getZeroBased() < model.getFilteredPersonList().size());
+
+ Person person = model.getFilteredPersonList().get(targetIndex.getZeroBased());
+ final String name = person.getName().fullName;
+ model.updateFilteredPersonList(new NameContainsKeywordsPredicate(name));
+
+ assertEquals(1, model.getFilteredPersonList().size());
+ }
+
+}
diff --git a/src/test/java/hirehive/address/logic/commands/DeleteCommandTest.java b/src/test/java/hirehive/address/logic/commands/DeleteCommandTest.java
new file mode 100644
index 00000000000..dce2a6d212f
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/commands/DeleteCommandTest.java
@@ -0,0 +1,111 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandFailure;
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static hirehive.address.logic.commands.CommandTestUtil.showPersonAtIndex;
+import static hirehive.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.model.person.Person;
+import hirehive.address.testutil.TypicalIndexes;
+import hirehive.address.testutil.TypicalPersons;
+
+
+/**
+ * Contains integration tests (interaction with the Model) and unit tests for
+ * {@code DeleteCommand}.
+ */
+public class DeleteCommandTest {
+
+ private Model model = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+
+ @Test
+ public void execute_validIndexUnfilteredList_success() {
+ Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
+ String nameToDelete = personToDelete.getName().fullName;
+
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(nameToDelete));
+ DeleteCommand deleteCommand = new DeleteCommand(nameQuery);
+
+ String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS,
+ Messages.format(personToDelete));
+
+ ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ expectedModel.deletePerson(personToDelete);
+
+ assertCommandSuccess(deleteCommand, model, new CommandResult(expectedMessage, true), expectedModel);
+ }
+
+ @Test
+ public void execute_nonexistentName_throwsCommandException() {
+ String nonexistentKeywords = "Nonexistent";
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(nonexistentKeywords));
+ DeleteCommand deleteCommand = new DeleteCommand(nameQuery);
+
+ assertThrows(CommandException.class, () -> deleteCommand.execute(model));
+ }
+
+ @Test
+ public void execute_invalidIndexUnfilteredList_throwsCommandException() {
+ Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1);
+ DeleteCommand deleteCommand = new DeleteCommand(outOfBoundIndex);
+
+ assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
+ }
+
+ @Test
+ public void execute_emptyList_throwsCommandException() {
+ model = new ModelManager();
+ assertThrows(CommandException.class, () -> new DeleteCommand(TypicalIndexes.INDEX_FIRST_PERSON).execute(model));
+ }
+
+ @Test
+ public void equals() {
+ NameQuery firstQuery = new NameQuery(new NameContainsKeywordsPredicate("Alice"));
+ NameQuery secondQuery = new NameQuery(new NameContainsKeywordsPredicate("Bob"));
+
+ DeleteCommand deleteFirstCommand = new DeleteCommand(firstQuery);
+ DeleteCommand deleteSecondCommand = new DeleteCommand(secondQuery);
+
+ // same object -> returns true
+ assertTrue(deleteFirstCommand.equals(deleteFirstCommand));
+
+ // same values -> returns true
+ DeleteCommand deleteFirstCommandCopy = new DeleteCommand(firstQuery);
+ assertTrue(deleteFirstCommand.equals(deleteFirstCommandCopy));
+
+ // different types -> returns false
+ assertFalse(deleteFirstCommand.equals(1));
+
+ // null -> returns false
+ assertFalse(deleteFirstCommand.equals(null));
+
+ // different person -> returns false
+ assertFalse(deleteFirstCommand.equals(deleteSecondCommand));
+ }
+
+ /**
+ * Updates {@code model}'s filtered list to show no one.
+ */
+ private void showNoPerson(Model model) {
+ model.updateFilteredPersonList(p -> false);
+
+ assertTrue(model.getFilteredPersonList().isEmpty());
+ }
+}
diff --git a/src/test/java/hirehive/address/logic/commands/DisplayNoteCommandTest.java b/src/test/java/hirehive/address/logic/commands/DisplayNoteCommandTest.java
new file mode 100644
index 00000000000..196cdd2cf20
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/commands/DisplayNoteCommandTest.java
@@ -0,0 +1,101 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.logic.commands.queries.exceptions.QueryException;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.model.person.Person;
+import hirehive.address.testutil.TypicalIndexes;
+import hirehive.address.testutil.TypicalPersons;
+
+/**
+ * Contains integration tests (interaction with the Model) and unit tests for
+ * {@code DisplayNoteCommand}.
+ */
+public class DisplayNoteCommandTest {
+
+ private Model model = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+
+ @Test
+ public void execute_validUniqueName_success() {
+ Person personToDisplay = model.getFilteredPersonList().get(TypicalIndexes.INDEX_FIRST_PERSON.getZeroBased());
+ String nameToDisplay = personToDisplay.getName().fullName;
+
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(nameToDisplay));
+ DisplayNoteCommand noteCommand = new DisplayNoteCommand(nameToDisplay);
+
+ String expectedMessage = String.format(DisplayNoteCommand.MESSAGE_SUCCESS, Messages.format(personToDisplay));
+
+ ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ try {
+ List personsToDisplay = nameQuery.query(expectedModel);
+ } catch (QueryException e) {
+ fail();
+ }
+
+ assertCommandSuccess(noteCommand, model, new CommandResult(expectedMessage, false, false, true, false), expectedModel);
+ }
+
+ @Test
+ public void execute_nonexistentName_throwsCommandException() {
+ String nonexistentKeyword = "Nonexistent";
+ DisplayNoteCommand noteCommand = new DisplayNoteCommand(nonexistentKeyword);
+
+ assertThrows(CommandException.class, () -> noteCommand.execute(model), Messages.MESSAGE_NO_SUCH_PERSON);
+ }
+
+ @Test
+ public void execute_multipleMatches_throwsCommandException() {
+ String multipleMatches = "Meier";
+ DisplayNoteCommand noteCommand = new DisplayNoteCommand(multipleMatches);
+
+ assertThrows(CommandException.class, () -> noteCommand.execute(model), Messages.MESSAGE_MULTIPLE_PEOPLE_QUERIED_NAME);
+ }
+
+ @Test
+ public void equals() {
+ DisplayNoteCommand noteFirstCommand = new DisplayNoteCommand("Alice");
+ DisplayNoteCommand noteSecondCommand = new DisplayNoteCommand("Bob");
+
+ // same object -> returns true
+ assertTrue(noteFirstCommand.equals(noteFirstCommand));
+
+ // same values -> returns true
+ DisplayNoteCommand noteFirstCommandCopy = new DisplayNoteCommand("Alice");
+ assertTrue(noteFirstCommand.equals(noteFirstCommandCopy));
+
+ // different type -> returns false
+ assertFalse(noteFirstCommand.equals(1));
+
+ // null object -> returns false
+ assertFalse(noteFirstCommand.equals(null));
+
+ // different values -> returns false
+ assertFalse(noteFirstCommand.equals(noteSecondCommand));
+
+ }
+
+ @Test
+ public void toStringMethod() {
+ String name = "Alice";
+ DisplayNoteCommand noteCommand = new DisplayNoteCommand(name);
+ String expected = DisplayNoteCommand.class.getCanonicalName() + "{name="
+ + name + "}";
+ assertEquals(expected, noteCommand.toString());
+ }
+}
diff --git a/src/test/java/seedu/address/logic/commands/EditCommandTest.java b/src/test/java/hirehive/address/logic/commands/EditCommandTest.java
similarity index 51%
rename from src/test/java/seedu/address/logic/commands/EditCommandTest.java
rename to src/test/java/hirehive/address/logic/commands/EditCommandTest.java
index 469dd97daa7..e82204fc3d2 100644
--- a/src/test/java/seedu/address/logic/commands/EditCommandTest.java
+++ b/src/test/java/hirehive/address/logic/commands/EditCommandTest.java
@@ -1,52 +1,51 @@
-package seedu.address.logic.commands;
-
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.commands.CommandTestUtil.DESC_AMY;
+import static hirehive.address.logic.commands.CommandTestUtil.DESC_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_TAG_CANDIDATE;
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandFailure;
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static hirehive.address.logic.commands.CommandTestUtil.showPersonAtIndex;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
import org.junit.jupiter.api.Test;
-import seedu.address.commons.core.index.Index;
-import seedu.address.logic.Messages;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.model.AddressBook;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.UserPrefs;
-import seedu.address.model.person.Person;
-import seedu.address.testutil.EditPersonDescriptorBuilder;
-import seedu.address.testutil.PersonBuilder;
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.logic.Messages;
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.person.Role;
+import hirehive.address.testutil.EditPersonDescriptorBuilder;
+import hirehive.address.testutil.PersonBuilder;
+import hirehive.address.testutil.TypicalIndexes;
+import hirehive.address.testutil.TypicalPersons;
/**
* Contains integration tests (interaction with the Model) and unit tests for EditCommand.
*/
public class EditCommandTest {
- private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private Model model = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
@Test
public void execute_allFieldsSpecifiedUnfilteredList_success() {
Person editedPerson = new PersonBuilder().build();
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(editedPerson).build();
- EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, descriptor);
+ EditCommand.EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(editedPerson).build();
+ EditCommand editCommand = new EditCommand(TypicalIndexes.INDEX_FIRST_PERSON, descriptor);
String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson));
Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs());
expectedModel.setPerson(model.getFilteredPersonList().get(0), editedPerson);
- assertCommandSuccess(editCommand, model, expectedMessage, expectedModel);
+ assertCommandSuccess(editCommand, model, new CommandResult(expectedMessage, true), expectedModel);
}
@Test
@@ -56,10 +55,10 @@ public void execute_someFieldsSpecifiedUnfilteredList_success() {
PersonBuilder personInList = new PersonBuilder(lastPerson);
Person editedPerson = personInList.withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB)
- .withTags(VALID_TAG_HUSBAND).build();
+ .withTag(VALID_TAG_CANDIDATE).build();
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB)
- .withPhone(VALID_PHONE_BOB).withTags(VALID_TAG_HUSBAND).build();
+ EditCommand.EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB)
+ .withPhone(VALID_PHONE_BOB).withTag(VALID_TAG_CANDIDATE).build();
EditCommand editCommand = new EditCommand(indexLastPerson, descriptor);
String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson));
@@ -67,28 +66,36 @@ public void execute_someFieldsSpecifiedUnfilteredList_success() {
Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs());
expectedModel.setPerson(lastPerson, editedPerson);
- assertCommandSuccess(editCommand, model, expectedMessage, expectedModel);
+ assertCommandSuccess(editCommand, model, new CommandResult(expectedMessage, true), expectedModel);
}
+ @Test
+ public void isAnyFieldEdited_onlyRoleEdited_returnsTrue() {
+ EditCommand.EditPersonDescriptor descriptor = new EditCommand.EditPersonDescriptor();
+ descriptor.setRole(new Role("Developer"));
+ assertTrue(descriptor.isAnyFieldEdited());
+ }
+
+
@Test
public void execute_noFieldSpecifiedUnfilteredList_success() {
- EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, new EditPersonDescriptor());
- Person editedPerson = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
+ EditCommand editCommand = new EditCommand(TypicalIndexes.INDEX_FIRST_PERSON, new EditCommand.EditPersonDescriptor());
+ Person editedPerson = model.getFilteredPersonList().get(TypicalIndexes.INDEX_FIRST_PERSON.getZeroBased());
String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson));
Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs());
- assertCommandSuccess(editCommand, model, expectedMessage, expectedModel);
+ assertCommandSuccess(editCommand, model, new CommandResult(expectedMessage, true), expectedModel);
}
@Test
public void execute_filteredList_success() {
- showPersonAtIndex(model, INDEX_FIRST_PERSON);
+ showPersonAtIndex(model, TypicalIndexes.INDEX_FIRST_PERSON);
- Person personInFilteredList = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
+ Person personInFilteredList = model.getFilteredPersonList().get(TypicalIndexes.INDEX_FIRST_PERSON.getZeroBased());
Person editedPerson = new PersonBuilder(personInFilteredList).withName(VALID_NAME_BOB).build();
- EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON,
+ EditCommand editCommand = new EditCommand(TypicalIndexes.INDEX_FIRST_PERSON,
new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build());
String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson));
@@ -96,25 +103,25 @@ public void execute_filteredList_success() {
Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs());
expectedModel.setPerson(model.getFilteredPersonList().get(0), editedPerson);
- assertCommandSuccess(editCommand, model, expectedMessage, expectedModel);
+ assertCommandSuccess(editCommand, model, new CommandResult(expectedMessage, true), expectedModel);
}
@Test
public void execute_duplicatePersonUnfilteredList_failure() {
- Person firstPerson = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(firstPerson).build();
- EditCommand editCommand = new EditCommand(INDEX_SECOND_PERSON, descriptor);
+ Person firstPerson = model.getFilteredPersonList().get(TypicalIndexes.INDEX_FIRST_PERSON.getZeroBased());
+ EditCommand.EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(firstPerson).build();
+ EditCommand editCommand = new EditCommand(TypicalIndexes.INDEX_SECOND_PERSON, descriptor);
assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_PERSON);
}
@Test
public void execute_duplicatePersonFilteredList_failure() {
- showPersonAtIndex(model, INDEX_FIRST_PERSON);
+ showPersonAtIndex(model, TypicalIndexes.INDEX_FIRST_PERSON);
// edit person in filtered list into a duplicate in address book
- Person personInList = model.getAddressBook().getPersonList().get(INDEX_SECOND_PERSON.getZeroBased());
- EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON,
+ Person personInList = model.getAddressBook().getPersonList().get(TypicalIndexes.INDEX_SECOND_PERSON.getZeroBased());
+ EditCommand editCommand = new EditCommand(TypicalIndexes.INDEX_FIRST_PERSON,
new EditPersonDescriptorBuilder(personInList).build());
assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_PERSON);
@@ -123,7 +130,7 @@ public void execute_duplicatePersonFilteredList_failure() {
@Test
public void execute_invalidPersonIndexUnfilteredList_failure() {
Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1);
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build();
+ EditCommand.EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build();
EditCommand editCommand = new EditCommand(outOfBoundIndex, descriptor);
assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
@@ -135,8 +142,8 @@ public void execute_invalidPersonIndexUnfilteredList_failure() {
*/
@Test
public void execute_invalidPersonIndexFilteredList_failure() {
- showPersonAtIndex(model, INDEX_FIRST_PERSON);
- Index outOfBoundIndex = INDEX_SECOND_PERSON;
+ showPersonAtIndex(model, TypicalIndexes.INDEX_FIRST_PERSON);
+ Index outOfBoundIndex = TypicalIndexes.INDEX_SECOND_PERSON;
// ensures that outOfBoundIndex is still in bounds of address book list
assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size());
@@ -146,13 +153,14 @@ public void execute_invalidPersonIndexFilteredList_failure() {
assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
}
+
@Test
public void equals() {
- final EditCommand standardCommand = new EditCommand(INDEX_FIRST_PERSON, DESC_AMY);
+ final EditCommand standardCommand = new EditCommand(TypicalIndexes.INDEX_FIRST_PERSON, DESC_AMY);
// same values -> returns true
- EditPersonDescriptor copyDescriptor = new EditPersonDescriptor(DESC_AMY);
- EditCommand commandWithSameValues = new EditCommand(INDEX_FIRST_PERSON, copyDescriptor);
+ EditCommand.EditPersonDescriptor copyDescriptor = new EditCommand.EditPersonDescriptor(DESC_AMY);
+ EditCommand commandWithSameValues = new EditCommand(TypicalIndexes.INDEX_FIRST_PERSON, copyDescriptor);
assertTrue(standardCommand.equals(commandWithSameValues));
// same object -> returns true
@@ -165,16 +173,31 @@ public void equals() {
assertFalse(standardCommand.equals(new ClearCommand()));
// different index -> returns false
- assertFalse(standardCommand.equals(new EditCommand(INDEX_SECOND_PERSON, DESC_AMY)));
+ assertFalse(standardCommand.equals(new EditCommand(TypicalIndexes.INDEX_SECOND_PERSON, DESC_AMY)));
// different descriptor -> returns false
- assertFalse(standardCommand.equals(new EditCommand(INDEX_FIRST_PERSON, DESC_BOB)));
+ assertFalse(standardCommand.equals(new EditCommand(TypicalIndexes.INDEX_FIRST_PERSON, DESC_BOB)));
+ }
+
+ @Test
+ public void equals_differentRole_returnsFalse() {
+ EditCommand.EditPersonDescriptor descriptorWithRole1 = new EditPersonDescriptorBuilder()
+ .withName(VALID_NAME_BOB)
+ .withRole("Software Engineer") // Role 1
+ .build();
+
+ EditCommand.EditPersonDescriptor descriptorWithRole2 = new EditPersonDescriptorBuilder()
+ .withName(VALID_NAME_BOB)
+ .withRole("Project Manager") // Different Role
+ .build();
+
+ assertFalse(descriptorWithRole1.equals(descriptorWithRole2));
}
@Test
public void toStringMethod() {
Index index = Index.fromOneBased(1);
- EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor();
+ EditCommand.EditPersonDescriptor editPersonDescriptor = new EditCommand.EditPersonDescriptor();
EditCommand editCommand = new EditCommand(index, editPersonDescriptor);
String expected = EditCommand.class.getCanonicalName() + "{index=" + index + ", editPersonDescriptor="
+ editPersonDescriptor + "}";
diff --git a/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java b/src/test/java/hirehive/address/logic/commands/EditPersonDescriptorTest.java
similarity index 51%
rename from src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java
rename to src/test/java/hirehive/address/logic/commands/EditPersonDescriptorTest.java
index b17c1f3d5c2..037d94d28f6 100644
--- a/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java
+++ b/src/test/java/hirehive/address/logic/commands/EditPersonDescriptorTest.java
@@ -1,27 +1,28 @@
-package seedu.address.logic.commands;
+package hirehive.address.logic.commands;
+import static hirehive.address.logic.commands.CommandTestUtil.DESC_AMY;
+import static hirehive.address.logic.commands.CommandTestUtil.DESC_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_NOTE_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_ROLE_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_TAG_CANDIDATE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
import org.junit.jupiter.api.Test;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.testutil.EditPersonDescriptorBuilder;
+import hirehive.address.testutil.EditPersonDescriptorBuilder;
public class EditPersonDescriptorTest {
@Test
public void equals() {
// same values -> returns true
- EditPersonDescriptor descriptorWithSameValues = new EditPersonDescriptor(DESC_AMY);
+ EditCommand.EditPersonDescriptor descriptorWithSameValues = new EditCommand.EditPersonDescriptor(DESC_AMY);
assertTrue(DESC_AMY.equals(descriptorWithSameValues));
// same object -> returns true
@@ -37,7 +38,7 @@ public void equals() {
assertFalse(DESC_AMY.equals(DESC_BOB));
// different name -> returns false
- EditPersonDescriptor editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withName(VALID_NAME_BOB).build();
+ EditCommand.EditPersonDescriptor editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withName(VALID_NAME_BOB).build();
assertFalse(DESC_AMY.equals(editedAmy));
// different phone -> returns false
@@ -52,20 +53,29 @@ public void equals() {
editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withAddress(VALID_ADDRESS_BOB).build();
assertFalse(DESC_AMY.equals(editedAmy));
+ editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withRole(VALID_ROLE_BOB).build();
+
// different tags -> returns false
- editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withTags(VALID_TAG_HUSBAND).build();
+ editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withTag(VALID_TAG_CANDIDATE).build();
+ assertFalse(DESC_AMY.equals(editedAmy));
+
+ // different note -> returns false
+ editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withNote(VALID_NOTE_BOB).build();
assertFalse(DESC_AMY.equals(editedAmy));
}
@Test
public void toStringMethod() {
- EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor();
- String expected = EditPersonDescriptor.class.getCanonicalName() + "{name="
+ EditCommand.EditPersonDescriptor editPersonDescriptor = new EditCommand.EditPersonDescriptor();
+ String expected = EditCommand.EditPersonDescriptor.class.getCanonicalName() + "{name="
+ editPersonDescriptor.getName().orElse(null) + ", phone="
+ editPersonDescriptor.getPhone().orElse(null) + ", email="
+ editPersonDescriptor.getEmail().orElse(null) + ", address="
- + editPersonDescriptor.getAddress().orElse(null) + ", tags="
- + editPersonDescriptor.getTags().orElse(null) + "}";
+ + editPersonDescriptor.getAddress().orElse(null) + ", role="
+ + editPersonDescriptor.getRole().orElse(null) + ", tag="
+ + editPersonDescriptor.getTag().orElse(null) + ", note="
+ + editPersonDescriptor.getNote().orElse(null) + ", interviewDate="
+ + editPersonDescriptor.getDate().orElse(null) + "}";
assertEquals(expected, editPersonDescriptor.toString());
}
}
diff --git a/src/test/java/seedu/address/logic/commands/ExitCommandTest.java b/src/test/java/hirehive/address/logic/commands/ExitCommandTest.java
similarity index 54%
rename from src/test/java/seedu/address/logic/commands/ExitCommandTest.java
rename to src/test/java/hirehive/address/logic/commands/ExitCommandTest.java
index 9533c473875..a37dcbc9d11 100644
--- a/src/test/java/seedu/address/logic/commands/ExitCommandTest.java
+++ b/src/test/java/hirehive/address/logic/commands/ExitCommandTest.java
@@ -1,12 +1,11 @@
-package seedu.address.logic.commands;
+package hirehive.address.logic.commands;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.logic.commands.ExitCommand.MESSAGE_EXIT_ACKNOWLEDGEMENT;
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandSuccess;
import org.junit.jupiter.api.Test;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
public class ExitCommandTest {
private Model model = new ModelManager();
@@ -14,7 +13,7 @@ public class ExitCommandTest {
@Test
public void execute_exit_success() {
- CommandResult expectedCommandResult = new CommandResult(MESSAGE_EXIT_ACKNOWLEDGEMENT, false, true);
+ CommandResult expectedCommandResult = new CommandResult(ExitCommand.MESSAGE_EXIT_ACKNOWLEDGEMENT, false, true, false, false);
assertCommandSuccess(new ExitCommand(), model, expectedCommandResult, expectedModel);
}
}
diff --git a/src/test/java/hirehive/address/logic/commands/FilterCommandTest.java b/src/test/java/hirehive/address/logic/commands/FilterCommandTest.java
new file mode 100644
index 00000000000..07a0511d521
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/commands/FilterCommandTest.java
@@ -0,0 +1,77 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static hirehive.address.testutil.Assert.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.parser.ParserUtil;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.model.person.PersonContainsTagPredicate;
+import hirehive.address.model.tag.Tag;
+import hirehive.address.testutil.TypicalPersons;
+
+/**
+ * Contains integration tests (interaction with the Model) for {@code FilterCommand}.
+ */
+public class FilterCommandTest {
+ private Model model = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+ private Model expectedModel = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+
+ @Test
+ public void equals() {
+ PersonContainsTagPredicate firstPredicate =
+ new PersonContainsTagPredicate(Tag.APPLICANT);
+ PersonContainsTagPredicate secondPredicate =
+ new PersonContainsTagPredicate(Tag.CANDIDATE);
+
+ FilterCommand filterFirstCommand = new FilterCommand(firstPredicate);
+ FilterCommand filterSecondCommand = new FilterCommand(secondPredicate);
+
+ // same object -> returns true
+ assertTrue(filterFirstCommand.equals(filterFirstCommand));
+
+ // same values -> returns true
+ FilterCommand findFirstCommandCopy = new FilterCommand(firstPredicate);
+ assertTrue(filterFirstCommand.equals(findFirstCommandCopy));
+
+ // different types -> returns false
+ assertFalse(filterFirstCommand.equals(1));
+
+ // null -> returns false
+ assertFalse(filterFirstCommand.equals(null));
+
+ // different person -> returns false
+ assertFalse(filterFirstCommand.equals(filterSecondCommand));
+ }
+
+ @Test
+ public void execute_zeroKeywords_throwsParseException() {
+ assertThrows(ParseException.class, () -> preparePredicate("test"));
+ }
+
+ @Test
+ public void execute_multipleKeywords_multiplePersonsFound() throws ParseException {
+ String expectedMessage = String.format(Messages.MESSAGE_FILTER_OVERVIEW_TAG, "REJECTED");
+ PersonContainsTagPredicate predicate = preparePredicate("Rejected");
+ FilterCommand command = new FilterCommand(predicate);
+ expectedModel.updateFilteredPersonList(predicate);
+ assertCommandSuccess(command, model, expectedMessage, expectedModel);
+ assertEquals(Arrays.asList(TypicalPersons.BENSON, TypicalPersons.ELLE,
+ TypicalPersons.FIONA), model.getFilteredPersonList());
+ }
+
+ private PersonContainsTagPredicate preparePredicate(String userInput) throws ParseException {
+ return new PersonContainsTagPredicate(ParserUtil.parseTag(userInput));
+ }
+}
diff --git a/src/test/java/hirehive/address/logic/commands/FilterOutCommandTest.java b/src/test/java/hirehive/address/logic/commands/FilterOutCommandTest.java
new file mode 100644
index 00000000000..d51a747c50a
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/commands/FilterOutCommandTest.java
@@ -0,0 +1,75 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import javax.swing.text.html.HTML;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.parser.ParserUtil;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.model.person.PersonDoesNotContainTagPredicate;
+import hirehive.address.model.tag.Tag;
+import hirehive.address.testutil.TypicalPersons;
+
+/**
+ * Contains integration tests (interaction with the Model) and unit tests for
+ * {@code FilterOutCommand}.
+ */
+public class FilterOutCommandTest {
+ private Model model = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+
+ @Test
+ public void execute_wrongInput_throwsParseException() {
+ assertThrows(ParseException.class, () -> preparePredicate("user"));
+ }
+
+ @Test
+ public void execute_validTagInput_success() throws ParseException {
+ PersonDoesNotContainTagPredicate filterOutPredicate = preparePredicate("applicant");
+ FilterOutCommand filterOutCommand = new FilterOutCommand(filterOutPredicate);
+ String expectedMessage = String.format(Messages.MESSAGE_FILTEROUT_OVERVIEW_TAG, "APPLICANT");
+ ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ expectedModel.updateFilteredPersonList(filterOutPredicate);
+
+ assertCommandSuccess(filterOutCommand, model, expectedMessage, expectedModel);
+ }
+
+ @Test
+ public void equals() {
+ PersonDoesNotContainTagPredicate firstPredicate =
+ new PersonDoesNotContainTagPredicate(Tag.APPLICANT);
+ PersonDoesNotContainTagPredicate secondPredicate =
+ new PersonDoesNotContainTagPredicate(Tag.CANDIDATE);
+
+ FilterOutCommand filteroutFirstCommand = new FilterOutCommand(firstPredicate);
+ FilterOutCommand filteroutSecondCommand = new FilterOutCommand(secondPredicate);
+
+ // same object -> returns true
+ assertTrue(filteroutFirstCommand.equals(filteroutFirstCommand));
+
+ // same values -> returns true
+ FilterOutCommand findFirstCommandCopy = new FilterOutCommand(firstPredicate);
+ assertTrue(filteroutFirstCommand.equals(findFirstCommandCopy));
+
+ // different types -> returns false
+ assertFalse(filteroutFirstCommand.equals(1));
+
+ // null -> returns false
+ assertFalse(filteroutFirstCommand.equals(null));
+
+ // different person -> returns false
+ assertFalse(filteroutFirstCommand.equals(filteroutSecondCommand));
+ }
+
+ private PersonDoesNotContainTagPredicate preparePredicate(String userInput) throws ParseException {
+ return new PersonDoesNotContainTagPredicate(ParserUtil.parseTag(userInput));
+ }
+}
diff --git a/src/test/java/hirehive/address/logic/commands/FindCommandTest.java b/src/test/java/hirehive/address/logic/commands/FindCommandTest.java
new file mode 100644
index 00000000000..271541099d0
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/commands/FindCommandTest.java
@@ -0,0 +1,80 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.testutil.TypicalPersons;
+
+/**
+ * Contains integration tests (interaction with the Model) for {@code FindCommand}.
+ */
+public class FindCommandTest {
+ private Model model = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+ private Model expectedModel = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+
+ @Test
+ public void equals() {
+ NameContainsKeywordsPredicate firstPredicate =
+ new NameContainsKeywordsPredicate("first");
+ NameContainsKeywordsPredicate secondPredicate =
+ new NameContainsKeywordsPredicate("second");
+
+ FindCommand findFirstCommand = new FindCommand(firstPredicate);
+ FindCommand findSecondCommand = new FindCommand(secondPredicate);
+
+ // same object -> returns true
+ assertTrue(findFirstCommand.equals(findFirstCommand));
+
+ // same values -> returns true
+ FindCommand findFirstCommandCopy = new FindCommand(firstPredicate);
+ assertTrue(findFirstCommand.equals(findFirstCommandCopy));
+
+ // different types -> returns false
+ assertFalse(findFirstCommand.equals(1));
+
+ // null -> returns false
+ assertFalse(findFirstCommand.equals(null));
+
+ // different person -> returns false
+ assertFalse(findFirstCommand.equals(findSecondCommand));
+ }
+
+ @Test
+ public void execute_zeroKeywords_throwsException() {
+ try {
+ String expectedMessage = String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, 0);
+ NameContainsKeywordsPredicate predicate = preparePredicate(" ");
+ FindCommand command = new FindCommand(predicate);
+ expectedModel.updateFilteredPersonList(predicate);
+ } catch (Exception e) {
+ assertEquals("Word parameter cannot be empty", e.getMessage());
+ }
+ }
+
+ @Test
+ public void toStringMethod() {
+ NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate("keyword");
+ FindCommand findCommand = new FindCommand(predicate);
+ String expected = FindCommand.class.getCanonicalName() + "{predicate=" + predicate + "}";
+ assertEquals(expected, findCommand.toString());
+ }
+
+ /**
+ * Parses {@code userInput} into a {@code NameContainsKeywordsPredicate}.
+ */
+ private NameContainsKeywordsPredicate preparePredicate(String userInput) {
+ return new NameContainsKeywordsPredicate(userInput);
+ }
+}
diff --git a/src/test/java/seedu/address/logic/commands/HelpCommandTest.java b/src/test/java/hirehive/address/logic/commands/HelpCommandTest.java
similarity index 55%
rename from src/test/java/seedu/address/logic/commands/HelpCommandTest.java
rename to src/test/java/hirehive/address/logic/commands/HelpCommandTest.java
index 4904fc4352e..8e8e7188d56 100644
--- a/src/test/java/seedu/address/logic/commands/HelpCommandTest.java
+++ b/src/test/java/hirehive/address/logic/commands/HelpCommandTest.java
@@ -1,12 +1,11 @@
-package seedu.address.logic.commands;
+package hirehive.address.logic.commands;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.logic.commands.HelpCommand.SHOWING_HELP_MESSAGE;
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandSuccess;
import org.junit.jupiter.api.Test;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
public class HelpCommandTest {
private Model model = new ModelManager();
@@ -14,7 +13,7 @@ public class HelpCommandTest {
@Test
public void execute_help_success() {
- CommandResult expectedCommandResult = new CommandResult(SHOWING_HELP_MESSAGE, true, false);
+ CommandResult expectedCommandResult = new CommandResult(HelpCommand.SHOWING_HELP_MESSAGE, true, false, false, false);
assertCommandSuccess(new HelpCommand(), model, expectedCommandResult, expectedModel);
}
}
diff --git a/src/test/java/seedu/address/logic/commands/ListCommandTest.java b/src/test/java/hirehive/address/logic/commands/ListCommandTest.java
similarity index 56%
rename from src/test/java/seedu/address/logic/commands/ListCommandTest.java
rename to src/test/java/hirehive/address/logic/commands/ListCommandTest.java
index 435ff1f7275..5e24e744ae3 100644
--- a/src/test/java/seedu/address/logic/commands/ListCommandTest.java
+++ b/src/test/java/hirehive/address/logic/commands/ListCommandTest.java
@@ -1,16 +1,16 @@
-package seedu.address.logic.commands;
+package hirehive.address.logic.commands;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static hirehive.address.logic.commands.CommandTestUtil.showPersonAtIndex;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.UserPrefs;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.testutil.TypicalIndexes;
+import hirehive.address.testutil.TypicalPersons;
/**
* Contains integration tests (interaction with the Model) and unit tests for ListCommand.
@@ -22,7 +22,7 @@ public class ListCommandTest {
@BeforeEach
public void setUp() {
- model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ model = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
}
@@ -33,7 +33,7 @@ public void execute_listIsNotFiltered_showsSameList() {
@Test
public void execute_listIsFiltered_showsEverything() {
- showPersonAtIndex(model, INDEX_FIRST_PERSON);
+ showPersonAtIndex(model, TypicalIndexes.INDEX_FIRST_PERSON);
assertCommandSuccess(new ListCommand(), model, ListCommand.MESSAGE_SUCCESS, expectedModel);
}
}
diff --git a/src/test/java/hirehive/address/logic/commands/NewNoteCommandTest.java b/src/test/java/hirehive/address/logic/commands/NewNoteCommandTest.java
new file mode 100644
index 00000000000..12523384ac5
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/commands/NewNoteCommandTest.java
@@ -0,0 +1,116 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.logic.commands.queries.exceptions.QueryException;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.model.person.Person;
+import hirehive.address.testutil.EditPersonDescriptorBuilder;
+import hirehive.address.testutil.PersonBuilder;
+import hirehive.address.testutil.TypicalPersons;
+
+public class NewNoteCommandTest {
+
+ private Model model = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+
+ @Test
+ public void execute_validUniqueName_success() {
+ Person editedPerson = new PersonBuilder(TypicalPersons.ALICE).withNote("test").build();
+ EditCommand.EditPersonDescriptor descriptor =
+ new EditPersonDescriptorBuilder(editedPerson).build();
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(TypicalPersons.ALICE.getName().fullName));
+ NewNoteCommand newNoteCommand = new NewNoteCommand(TypicalPersons.ALICE.getName().fullName, descriptor);
+
+ String expectedMessage = String.format(NewNoteCommand.MESSAGE_SUCCESS, Messages.format(editedPerson));
+
+ ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ List personsToAddNote;
+ try {
+ personsToAddNote = nameQuery.query(expectedModel);
+ expectedModel.setPerson(personsToAddNote.get(0), editedPerson);
+ } catch (QueryException e) {
+ fail();
+ }
+
+ assertCommandSuccess(newNoteCommand, model, new CommandResult(expectedMessage, false, false, true, true), expectedModel);
+ }
+
+ @Test
+ public void execute_nonexistentName_throwsCommandException() {
+ String name = "Nonexistent";
+ EditCommand.EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().build();
+ NewNoteCommand newNoteCommand = new NewNoteCommand(name, descriptor);
+
+ assertThrows(CommandException.class, () -> newNoteCommand.execute(model), Messages.MESSAGE_NO_SUCH_PERSON);
+ }
+
+ @Test
+ public void execute_multipleMatches_throwsCommandException() {
+ String name = "Meier";
+ EditCommand.EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().build();
+ NewNoteCommand newNoteCommand = new NewNoteCommand(name, descriptor);
+
+ assertThrows(CommandException.class, () -> newNoteCommand.execute(model), Messages.MESSAGE_MULTIPLE_PEOPLE_QUERIED_NAME);
+ }
+
+ @Test
+ public void equals() {
+ EditCommand.EditPersonDescriptor firstDescriptor = new EditPersonDescriptorBuilder().withNote("first").build();
+ EditCommand.EditPersonDescriptor secondDescriptor = new EditPersonDescriptorBuilder().withNote("second").build();
+
+ NewNoteCommand newNoteFirstCommand = new NewNoteCommand("Alice", firstDescriptor);
+ NewNoteCommand newNoteSecondCommand = new NewNoteCommand("Bob", secondDescriptor);
+
+ // same object -> returns true
+ assertTrue(newNoteFirstCommand.equals(newNoteFirstCommand));
+ assertTrue(newNoteSecondCommand.equals(newNoteSecondCommand));
+
+ // same values -> returns true
+ NewNoteCommand newNoteFirstCopy = new NewNoteCommand("Alice", firstDescriptor);
+ NewNoteCommand newNoteSecondCopy = new NewNoteCommand("Bob", secondDescriptor);
+ assertTrue(newNoteFirstCommand.equals(newNoteFirstCopy));
+ assertTrue(newNoteSecondCommand.equals(newNoteSecondCopy));
+
+ // different type -> returns false
+ assertFalse(newNoteFirstCommand.equals(0));
+ assertFalse(newNoteSecondCommand.equals(true));
+
+ // null object -> returns false
+ assertFalse(newNoteFirstCommand.equals(null));
+ assertFalse(newNoteSecondCommand.equals(null));
+
+ // different values -> returns false
+ assertFalse(newNoteFirstCommand.equals(newNoteSecondCommand));
+ NewNoteCommand newNoteFirstSecond = new NewNoteCommand("Alice", secondDescriptor);
+ NewNoteCommand newNoteSecondFirst = new NewNoteCommand("Bob", firstDescriptor);
+ assertFalse(newNoteFirstCommand.equals(newNoteFirstSecond));
+ assertFalse(newNoteFirstCommand.equals(newNoteSecondFirst));
+ assertFalse(newNoteSecondCommand.equals(newNoteFirstSecond));
+ assertFalse(newNoteSecondCommand.equals(newNoteSecondFirst));
+ }
+
+ @Test
+ public void toStringMethod() {
+ String name = TypicalPersons.ALICE.getName().fullName;
+ EditCommand.EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().build();
+ NewNoteCommand newNoteCommand = new NewNoteCommand(TypicalPersons.ALICE.getName().fullName, descriptor);
+
+ String expected = NewNoteCommand.class.getCanonicalName() + "{name=" + name + ", editPersonDescriptor=" + descriptor + "}";
+ assertEquals(expected, newNoteCommand.toString());
+ }
+}
diff --git a/src/test/java/hirehive/address/logic/commands/ReminderCommandTest.java b/src/test/java/hirehive/address/logic/commands/ReminderCommandTest.java
new file mode 100644
index 00000000000..d30a5a92e24
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/commands/ReminderCommandTest.java
@@ -0,0 +1,114 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.model.person.UpcomingInterviewPredicate;
+import hirehive.address.testutil.TypicalPersons;
+
+public class ReminderCommandTest {
+ private Model model = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+ private Model expectedModel = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+
+ @Test
+ public void equals() {
+ UpcomingInterviewPredicate firstPredicate =
+ new UpcomingInterviewPredicate(5, "01/01/2025");
+ UpcomingInterviewPredicate secondPredicate =
+ new UpcomingInterviewPredicate(10, "01/01/2025");
+
+ ReminderCommand reminderFirstCommand = new ReminderCommand(firstPredicate);
+ ReminderCommand reminderSecondCommand = new ReminderCommand(secondPredicate);
+
+ // same object -> returns true
+ assertTrue(reminderFirstCommand.equals(reminderFirstCommand));
+
+ // same values -> returns true
+ ReminderCommand findFirstCommandCopy = new ReminderCommand(firstPredicate);
+ assertTrue(reminderFirstCommand.equals(findFirstCommandCopy));
+
+ // different types -> returns false
+ assertFalse(reminderFirstCommand.equals(1));
+
+ // null -> returns false
+ assertFalse(reminderFirstCommand.equals(null));
+
+ // different days -> returns false
+ assertFalse(reminderFirstCommand.equals(reminderSecondCommand));
+ }
+
+ @Test
+ public void execute_zeroDays_noPersonFound() {
+ String expectedMessage = Messages.MESSAGE_NO_SUCH_PERSON;
+ UpcomingInterviewPredicate predicate = preparePredicate(0, "01/01/2025");
+ ReminderCommand command = new ReminderCommand(predicate);
+ expectedModel.updateFilteredPersonList(predicate);
+ assertCommandSuccess(command, model, expectedMessage, expectedModel);
+ assertEquals(Collections.emptyList(), model.getFilteredPersonList());
+ }
+
+ @Test
+ public void execute_zeroDays_onePersonFound() {
+ String expectedMessage = String.format(Messages.MESSAGE_FILTER_OVERVIEW_DATE, 0);
+ UpcomingInterviewPredicate predicate = preparePredicate(0, "01/02/2025");
+ ReminderCommand command = new ReminderCommand(predicate);
+ expectedModel.updateFilteredPersonList(predicate);
+ assertCommandSuccess(command, model, expectedMessage, expectedModel);
+ assertEquals(Arrays.asList(TypicalPersons.BENSON), model.getFilteredPersonList());
+ }
+
+ @Test
+ public void execute_zeroDays_multiplePersonsFound() {
+ String expectedMessage = String.format(Messages.MESSAGE_FILTER_OVERVIEW_DATE, 0);
+ UpcomingInterviewPredicate predicate = preparePredicate(0, "01/03/2025");
+ ReminderCommand command = new ReminderCommand(predicate);
+ expectedModel.updateFilteredPersonList(predicate);
+ assertCommandSuccess(command, model, expectedMessage, expectedModel);
+ assertEquals(Arrays.asList(TypicalPersons.ELLE, TypicalPersons.FIONA), model.getFilteredPersonList());
+ }
+
+ @Test
+ public void execute_nonZeroDays_noPersonsFound() {
+ String expectedMessage = Messages.MESSAGE_NO_SUCH_PERSON;
+ UpcomingInterviewPredicate predicate = preparePredicate(10, "01/01/2024");
+ ReminderCommand command = new ReminderCommand(predicate);
+ expectedModel.updateFilteredPersonList(predicate);
+ assertCommandSuccess(command, model, expectedMessage, expectedModel);
+ assertEquals(Collections.emptyList(), model.getFilteredPersonList());
+ }
+
+ @Test
+ public void execute_nonZeroDays_onePersonFound() {
+ String expectedMessage = String.format(Messages.MESSAGE_FILTER_OVERVIEW_DATE, 10);
+ UpcomingInterviewPredicate predicate = preparePredicate(10, "22/01/2025");
+ ReminderCommand command = new ReminderCommand(predicate);
+ expectedModel.updateFilteredPersonList(predicate);
+ assertCommandSuccess(command, model, expectedMessage, expectedModel);
+ assertEquals(Arrays.asList(TypicalPersons.BENSON), model.getFilteredPersonList());
+ }
+
+ @Test
+ public void execute_nonZeroDays_multiplePersonsFound() {
+ String expectedMessage = String.format(Messages.MESSAGE_FILTER_OVERVIEW_DATE, 10);
+ UpcomingInterviewPredicate predicate = preparePredicate(10, "21/02/2025");
+ ReminderCommand command = new ReminderCommand(predicate);
+ expectedModel.updateFilteredPersonList(predicate);
+ assertCommandSuccess(command, model, expectedMessage, expectedModel);
+ assertEquals(Arrays.asList(TypicalPersons.ELLE, TypicalPersons.FIONA), model.getFilteredPersonList());
+ }
+
+ private UpcomingInterviewPredicate preparePredicate(int userInput, String currDay) {
+ return new UpcomingInterviewPredicate(userInput, currDay);
+ }
+}
diff --git a/src/test/java/hirehive/address/logic/commands/ScheduleCommandTest.java b/src/test/java/hirehive/address/logic/commands/ScheduleCommandTest.java
new file mode 100644
index 00000000000..42d7e37472f
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/commands/ScheduleCommandTest.java
@@ -0,0 +1,250 @@
+package hirehive.address.logic.commands;
+
+import static hirehive.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.ResolverStyle;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.exceptions.CommandException;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.logic.commands.queries.exceptions.QueryException;
+import hirehive.address.logic.parser.ParserUtil;
+import hirehive.address.logic.parser.ParserUtilTest;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.tag.Tag;
+import hirehive.address.testutil.EditPersonDescriptorBuilder;
+import hirehive.address.testutil.PersonBuilder;
+import hirehive.address.testutil.TypicalPersons;
+
+public class ScheduleCommandTest {
+ private Model model = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+
+ @Test
+ public void execute_validApplicantNameAndDate_success() {
+ Person editedPerson = new PersonBuilder(TypicalPersons.ALICE).withDate("31/12/2025").withTag("INTERVIEWEE").build();
+ EditCommand.EditPersonDescriptor descriptor =
+ new EditPersonDescriptorBuilder(editedPerson).build();
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(TypicalPersons.ALICE.getName().fullName));
+ ScheduleCommand scheduleCommand = new ScheduleCommand(nameQuery, descriptor);
+
+ String expectedMessage = String.format(ScheduleCommand.MESSAGE_DATE_PERSON_SUCCESS, Messages.format(editedPerson));
+
+ ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ List personsToAddNote;
+ try {
+ personsToAddNote = nameQuery.query(expectedModel);
+ expectedModel.setPerson(personsToAddNote.get(0), editedPerson);
+ } catch (QueryException e) {
+ fail();
+ }
+
+ assertCommandSuccess(scheduleCommand, model, new CommandResult(expectedMessage, true), expectedModel);
+ }
+
+ @Test
+ public void execute_validApplicantIndexAndDate_success() {
+ Person editedPerson = new PersonBuilder(TypicalPersons.ALICE).withDate("31/12/2025").withTag("INTERVIEWEE").build();
+ EditCommand.EditPersonDescriptor descriptor =
+ new EditPersonDescriptorBuilder(editedPerson).build();
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(TypicalPersons.ALICE.getName().fullName));
+ Index index = null;
+ try {
+ index = ParserUtil.parseIndex("1");
+ } catch (Exception e) {
+ assert false;
+ }
+ ScheduleCommand scheduleCommand = new ScheduleCommand(index, descriptor);
+
+ String expectedMessage = String.format(ScheduleCommand.MESSAGE_DATE_PERSON_SUCCESS, Messages.format(editedPerson));
+
+ ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ List personsToAddNote;
+ try {
+ personsToAddNote = nameQuery.query(expectedModel);
+ expectedModel.setPerson(personsToAddNote.get(0), editedPerson);
+ } catch (QueryException e) {
+ fail();
+ }
+ System.out.println(model.getAddressBook().toString());
+ assertCommandSuccess(scheduleCommand, model, new CommandResult(expectedMessage, true), expectedModel);
+ }
+
+ @Test
+ public void execute_validIntervieweeNameAndDate_success() {
+ Person editedPerson = new PersonBuilder(TypicalPersons.CARL).withDate("31/12/2025").build();
+ EditCommand.EditPersonDescriptor descriptor =
+ new EditPersonDescriptorBuilder(editedPerson).build();
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(TypicalPersons.CARL.getName().fullName));
+ ScheduleCommand scheduleCommand = new ScheduleCommand(nameQuery, descriptor);
+
+ String expectedMessage = String.format(ScheduleCommand.MESSAGE_DATE_PERSON_SUCCESS, Messages.format(editedPerson));
+
+ ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ List personsToEdit;
+ try {
+ personsToEdit = nameQuery.query(expectedModel);
+ expectedModel.setPerson(personsToEdit.get(0), editedPerson);
+ } catch (QueryException e) {
+ fail();
+ }
+
+ assertCommandSuccess(scheduleCommand, model, new CommandResult(expectedMessage, true), expectedModel);
+ }
+
+ @Test
+ public void execute_validInterviewIndexAndDate_success() {
+ Person editedPerson = new PersonBuilder(TypicalPersons.CARL).withDate("31/12/2025").build();
+ EditCommand.EditPersonDescriptor descriptor =
+ new EditPersonDescriptorBuilder(editedPerson).build();
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(TypicalPersons.CARL.getName().fullName));
+ Index index = null;
+ try {
+ index = ParserUtil.parseIndex("3");
+ } catch (Exception e) {
+ assert false;
+ }
+ ScheduleCommand scheduleCommand = new ScheduleCommand(index, descriptor);
+
+ String expectedMessage = String.format(ScheduleCommand.MESSAGE_DATE_PERSON_SUCCESS, Messages.format(editedPerson));
+
+ ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ List personsToAddNote;
+ try {
+ personsToAddNote = nameQuery.query(expectedModel);
+ expectedModel.setPerson(personsToAddNote.get(0), editedPerson);
+ } catch (QueryException e) {
+ fail();
+ }
+ System.out.println(model.getAddressBook().toString());
+ assertCommandSuccess(scheduleCommand, model, new CommandResult(expectedMessage, true), expectedModel);
+ }
+
+ @Test
+ public void execute_validApplicantNameWithoutDate_success() {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu")
+ .withResolverStyle(ResolverStyle.STRICT);
+ Person editedPerson = new PersonBuilder(TypicalPersons.ALICE)
+ .withDate(LocalDate.now().plusDays(1).format(formatter))
+ .withTag("INTERVIEWEE").build();
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(TypicalPersons.ALICE.getName().fullName));
+ ScheduleCommand scheduleCommand = new ScheduleCommand(nameQuery);
+
+ String expectedMessage = String.format(ScheduleCommand.MESSAGE_DATE_PERSON_SUCCESS, Messages.format(editedPerson));
+
+ ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ List personsToAddNote;
+ try {
+ personsToAddNote = nameQuery.query(expectedModel);
+ expectedModel.setPerson(personsToAddNote.get(0), editedPerson);
+ } catch (QueryException e) {
+ fail();
+ }
+
+ assertCommandSuccess(scheduleCommand, model, new CommandResult(expectedMessage, true), expectedModel);
+ }
+
+ @Test
+ public void execute_validApplicantIndexWithoutDate_success() {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu")
+ .withResolverStyle(ResolverStyle.STRICT);
+ Person editedPerson = new PersonBuilder(TypicalPersons.ALICE)
+ .withDate(LocalDate.now().plusDays(1).format(formatter))
+ .withTag("INTERVIEWEE").build();
+ EditCommand.EditPersonDescriptor descriptor =
+ new EditPersonDescriptorBuilder(editedPerson).build();
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(TypicalPersons.ALICE.getName().fullName));
+ Index index = null;
+ try {
+ index = ParserUtil.parseIndex("1");
+ } catch (Exception e) {
+ assert false;
+ }
+ ScheduleCommand scheduleCommand = new ScheduleCommand(index);
+
+ String expectedMessage = String.format(ScheduleCommand.MESSAGE_DATE_PERSON_SUCCESS, Messages.format(editedPerson));
+
+ ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ List personsToAddNote;
+ try {
+ personsToAddNote = nameQuery.query(expectedModel);
+ expectedModel.setPerson(personsToAddNote.get(0), editedPerson);
+ } catch (QueryException e) {
+ fail();
+ }
+ System.out.println(model.getAddressBook().toString());
+ assertCommandSuccess(scheduleCommand, model, new CommandResult(expectedMessage, true), expectedModel);
+ }
+
+ @Test
+ public void execute_invalidTag_throwsCommandException() {
+ EditCommand.EditPersonDescriptor descriptor =
+ new EditPersonDescriptorBuilder().build();
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(TypicalPersons.BENSON.getName().fullName));
+ ScheduleCommand scheduleCommand = new ScheduleCommand(nameQuery, descriptor);
+ assertThrows(CommandException.class, () -> scheduleCommand.execute(model), String.format(ScheduleCommand.MESSAGE_INVALID_PERSON,
+ TypicalPersons.BENSON.getName().fullName, TypicalPersons.BENSON.getTag().getTagName()));
+ }
+
+ @Test
+ public void execute_invalidName_throwsCommandException() {
+ String name = "Nonexistent";
+ EditCommand.EditPersonDescriptor descriptor =
+ new EditPersonDescriptorBuilder().build();
+ NameQuery nameQuery = new NameQuery(new NameContainsKeywordsPredicate(name));
+ ScheduleCommand scheduleCommand = new ScheduleCommand(nameQuery, descriptor);
+ assertThrows(CommandException.class, () -> scheduleCommand.execute(model), Messages.MESSAGE_NO_SUCH_PERSON);
+ }
+
+ @Test
+ public void equals() {
+ NameQuery firstQuery = new NameQuery(new NameContainsKeywordsPredicate("Alice"));
+ NameQuery secondQuery = new NameQuery(new NameContainsKeywordsPredicate("Bob"));
+ EditCommand.EditPersonDescriptor firstDescriptor = new EditPersonDescriptorBuilder().withDate("01/01/2025").build();
+ EditCommand.EditPersonDescriptor secondDescriptor = new EditPersonDescriptorBuilder().withDate("02/01/2025").build();
+
+ ScheduleCommand firstCommand = new ScheduleCommand(firstQuery, firstDescriptor);
+ ScheduleCommand secondCommand = new ScheduleCommand(secondQuery, secondDescriptor);
+
+ // same object -> returns true
+ assertTrue(firstCommand.equals(firstCommand));
+ assertTrue(secondCommand.equals(secondCommand));
+
+ // same values -> returns true
+ ScheduleCommand firstCopy = new ScheduleCommand(firstQuery, firstDescriptor);
+ ScheduleCommand secondCopy = new ScheduleCommand(secondQuery, secondDescriptor);
+ assertTrue(firstCommand.equals(firstCopy));
+ assertTrue(secondCommand.equals(secondCopy));
+
+ // different type -> returns false
+ assertFalse(firstCommand.equals(0));
+ assertFalse(secondCommand.equals(true));
+
+ // null object -> returns false
+ assertFalse(firstCommand.equals(null));
+ assertFalse(secondCommand.equals(null));
+
+ // different values -> returns false
+ assertFalse(firstCommand.equals(secondCommand));
+ ScheduleCommand firstSecond = new ScheduleCommand(firstQuery, secondDescriptor);
+ ScheduleCommand secondFirst = new ScheduleCommand(secondQuery, firstDescriptor);
+ assertFalse(firstCommand.equals(firstSecond));
+ assertFalse(firstCommand.equals(secondFirst));
+ assertFalse(secondCommand.equals(firstSecond));
+ assertFalse(secondCommand.equals(secondFirst));
+ }
+}
diff --git a/src/test/java/hirehive/address/logic/commands/SortCommandTest.java b/src/test/java/hirehive/address/logic/commands/SortCommandTest.java
new file mode 100644
index 00000000000..cc78248c916
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/commands/SortCommandTest.java
@@ -0,0 +1,51 @@
+package hirehive.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 java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.Model;
+import hirehive.address.model.ModelManager;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.model.person.Person;
+import hirehive.address.testutil.TypicalPersons;
+
+public class SortCommandTest {
+
+ @Test
+ public void execute_sortCommand_sortsApplicantsByDate() {
+ Model model = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+ Model expectedModel = new ModelManager(TypicalPersons.getTypicalAddressBook(), new UserPrefs());
+ SortCommand sortCommand = new SortCommand();
+
+ // Execute sorting on both models
+ sortCommand.execute(model);
+ expectedModel.sortPersons();
+
+ // Check if both models are now sorted in the same way
+ assertEquals(expectedModel.getFilteredPersonList(), model.getFilteredPersonList());
+ }
+
+ @Test
+ public void execute_sortCommand_placesNoInterviewDateAtEnd() {
+ Model sortingModel = new ModelManager(new AddressBook(), new UserPrefs());
+ sortingModel.addPerson(TypicalPersons.ELLE);
+ sortingModel.addPerson(TypicalPersons.ALICE);
+ sortingModel.addPerson(TypicalPersons.BENSON);
+
+ SortCommand sortCommand = new SortCommand();
+ sortCommand.execute(sortingModel);
+
+ List sortedList = sortingModel.getFilteredPersonList();
+
+ // Ensure people with interview dates come first
+ assertTrue(sortedList.get(0).getDate().getValue().isPresent());
+ assertTrue(sortedList.get(1).getDate().getValue().isPresent());
+ assertFalse(sortedList.get(2).getDate().getValue().isPresent()); // No date, should be last
+ }
+}
diff --git a/src/test/java/hirehive/address/logic/parser/AddCommandParserTest.java b/src/test/java/hirehive/address/logic/parser/AddCommandParserTest.java
new file mode 100644
index 00000000000..3f2b2cc5dc4
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/parser/AddCommandParserTest.java
@@ -0,0 +1,170 @@
+package hirehive.address.logic.parser;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.AddCommand;
+import hirehive.address.logic.commands.CommandTestUtil;
+import hirehive.address.model.person.Address;
+import hirehive.address.model.person.Email;
+import hirehive.address.model.person.Name;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.person.Phone;
+import hirehive.address.model.person.Role;
+import hirehive.address.model.tag.Tag;
+import hirehive.address.testutil.PersonBuilder;
+import hirehive.address.testutil.TypicalPersons;
+
+public class AddCommandParserTest {
+ private AddCommandParser parser = new AddCommandParser();
+
+ @Test
+ public void parse_allFieldsPresent_success() {
+ Person expectedPerson = new PersonBuilder(TypicalPersons.BOB).build();
+
+ // whitespace only preamble
+ CommandParserTestUtil.assertParseSuccess(parser, CommandTestUtil.PREAMBLE_WHITESPACE
+ + CommandTestUtil.NAME_DESC_BOB + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.EMAIL_DESC_BOB
+ + CommandTestUtil.ADDRESS_DESC_BOB + CommandTestUtil.ROLE_DESC_BOB, new AddCommand(expectedPerson));
+ }
+
+ @Test
+ public void parse_repeatedNonTagValue_failure() {
+ String validExpectedPersonString = CommandTestUtil.NAME_DESC_BOB + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.EMAIL_DESC_BOB
+ + CommandTestUtil.ADDRESS_DESC_BOB + CommandTestUtil.ROLE_DESC_BOB + CommandTestUtil.TAG_DESC_APPLICANT;
+
+ // multiple names
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.NAME_DESC_AMY + validExpectedPersonString,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_NAME));
+
+ // multiple phones
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.PHONE_DESC_AMY + validExpectedPersonString,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_PHONE));
+
+ // multiple emails
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.EMAIL_DESC_AMY + validExpectedPersonString,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_EMAIL));
+
+ // multiple addresses
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.ADDRESS_DESC_AMY + validExpectedPersonString,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_ADDRESS));
+
+ // multiple fields repeated
+ CommandParserTestUtil.assertParseFailure(parser,
+ validExpectedPersonString + CommandTestUtil.PHONE_DESC_AMY + CommandTestUtil.EMAIL_DESC_AMY
+ + CommandTestUtil.NAME_DESC_AMY + CommandTestUtil.ADDRESS_DESC_AMY + CommandTestUtil.ROLE_DESC_AMY
+ + CommandTestUtil.NOTE_DESC_AMY + validExpectedPersonString,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_NAME, CliSyntax.PREFIX_ADDRESS, CliSyntax.PREFIX_EMAIL, CliSyntax.PREFIX_PHONE,
+ CliSyntax.PREFIX_ROLE));
+
+ // invalid value followed by valid value
+
+ // invalid name
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.INVALID_NAME_DESC + validExpectedPersonString,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_NAME));
+
+ // invalid email
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.INVALID_EMAIL_DESC + validExpectedPersonString,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_EMAIL));
+
+ // invalid phone
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.INVALID_PHONE_DESC + validExpectedPersonString,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_PHONE));
+
+ // invalid address
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.INVALID_ADDRESS_DESC + validExpectedPersonString,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_ADDRESS));
+
+ // valid value followed by invalid value
+
+ // invalid name
+ CommandParserTestUtil.assertParseFailure(parser, validExpectedPersonString + CommandTestUtil.INVALID_NAME_DESC,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_NAME));
+
+ // invalid email
+ CommandParserTestUtil.assertParseFailure(parser, validExpectedPersonString + CommandTestUtil.INVALID_EMAIL_DESC,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_EMAIL));
+
+ // invalid phone
+ CommandParserTestUtil.assertParseFailure(parser, validExpectedPersonString + CommandTestUtil.INVALID_PHONE_DESC,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_PHONE));
+
+ // invalid address
+ CommandParserTestUtil.assertParseFailure(parser, validExpectedPersonString + CommandTestUtil.INVALID_ADDRESS_DESC,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_ADDRESS));
+ }
+
+ @Test
+ public void parse_optionalFieldsMissing_success() {
+ // zero tags
+ Person expectedPerson = new PersonBuilder(TypicalPersons.BOB).build();
+ CommandParserTestUtil.assertParseSuccess(parser, CommandTestUtil.NAME_DESC_BOB + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.EMAIL_DESC_BOB + CommandTestUtil.ADDRESS_DESC_BOB
+ + CommandTestUtil.ROLE_DESC_BOB,
+ new AddCommand(expectedPerson));
+
+ // no notes
+ expectedPerson = new PersonBuilder(TypicalPersons.BOB).build();
+ CommandParserTestUtil.assertParseSuccess(parser, CommandTestUtil.NAME_DESC_BOB + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.EMAIL_DESC_BOB + CommandTestUtil.ADDRESS_DESC_BOB
+ + CommandTestUtil.ROLE_DESC_BOB,
+ new AddCommand(expectedPerson));
+ }
+
+ @Test
+ public void parse_compulsoryFieldMissing_failure() {
+ String expectedMessage = String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE);
+
+ // missing name prefix
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.VALID_NAME_BOB + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.EMAIL_DESC_BOB + CommandTestUtil.ADDRESS_DESC_BOB
+ + CommandTestUtil.ROLE_DESC_BOB, expectedMessage);
+
+ // missing phone prefix
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.NAME_DESC_BOB + CommandTestUtil.VALID_PHONE_BOB + CommandTestUtil.EMAIL_DESC_BOB + CommandTestUtil.ADDRESS_DESC_BOB
+ + CommandTestUtil.ROLE_DESC_BOB, expectedMessage);
+
+ // missing email prefix
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.NAME_DESC_BOB + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.VALID_EMAIL_BOB + CommandTestUtil.ADDRESS_DESC_BOB
+ + CommandTestUtil.ROLE_DESC_BOB, expectedMessage);
+
+ // missing address prefix
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.NAME_DESC_BOB + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.EMAIL_DESC_BOB + CommandTestUtil.VALID_ADDRESS_BOB
+ + CommandTestUtil.ROLE_DESC_BOB, expectedMessage);
+
+ // all prefixes missing
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.VALID_NAME_BOB + CommandTestUtil.VALID_PHONE_BOB + CommandTestUtil.VALID_EMAIL_BOB + CommandTestUtil.VALID_ADDRESS_BOB
+ + CommandTestUtil.VALID_ROLE_BOB, expectedMessage);
+ }
+
+ @Test
+ public void parse_invalidValue_failure() {
+ // invalid name
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.INVALID_NAME_DESC + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.EMAIL_DESC_BOB + CommandTestUtil.ADDRESS_DESC_BOB
+ + CommandTestUtil.ROLE_DESC_BOB + CommandTestUtil.VALID_TAG_CANDIDATE + CommandTestUtil.DEFAULT_TAG_APPLICANT, Name.MESSAGE_CONSTRAINTS);
+
+ // invalid phone
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.NAME_DESC_BOB + CommandTestUtil.INVALID_PHONE_DESC + CommandTestUtil.EMAIL_DESC_BOB + CommandTestUtil.ADDRESS_DESC_BOB
+ + CommandTestUtil.ROLE_DESC_BOB + CommandTestUtil.VALID_TAG_CANDIDATE + CommandTestUtil.DEFAULT_TAG_APPLICANT, Phone.MESSAGE_CONSTRAINTS);
+
+ // invalid email
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.NAME_DESC_BOB + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.INVALID_EMAIL_DESC + CommandTestUtil.ADDRESS_DESC_BOB
+ + CommandTestUtil.ROLE_DESC_BOB + CommandTestUtil.VALID_TAG_CANDIDATE + CommandTestUtil.DEFAULT_TAG_APPLICANT, Email.MESSAGE_CONSTRAINTS);
+
+ // invalid address
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.NAME_DESC_BOB + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.EMAIL_DESC_BOB + CommandTestUtil.INVALID_ADDRESS_DESC
+ + CommandTestUtil.ROLE_DESC_BOB + CommandTestUtil.VALID_TAG_CANDIDATE + CommandTestUtil.DEFAULT_TAG_APPLICANT, Address.MESSAGE_CONSTRAINTS);
+
+ // tag was incorrectly given
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.NAME_DESC_BOB + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.EMAIL_DESC_BOB + CommandTestUtil.ADDRESS_DESC_BOB
+ + CommandTestUtil.ROLE_DESC_BOB + CommandTestUtil.INVALID_TAG_DESC + CommandTestUtil.VALID_TAG_APPLICANT,
+ Role.MESSAGE_CONSTRAINTS);
+
+ // two invalid values, only first invalid value reported
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.INVALID_NAME_DESC + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.EMAIL_DESC_BOB + CommandTestUtil.INVALID_ADDRESS_DESC
+ + CommandTestUtil.ROLE_DESC_BOB, Name.MESSAGE_CONSTRAINTS);
+
+ // non-empty preamble
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.PREAMBLE_NON_EMPTY + CommandTestUtil.NAME_DESC_BOB + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.EMAIL_DESC_BOB
+ + CommandTestUtil.ADDRESS_DESC_BOB + CommandTestUtil.ROLE_DESC_BOB + CommandTestUtil.VALID_TAG_CANDIDATE + CommandTestUtil.TAG_DESC_APPLICANT,
+ String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));
+ }
+}
diff --git a/src/test/java/hirehive/address/logic/parser/AddressBookParserTest.java b/src/test/java/hirehive/address/logic/parser/AddressBookParserTest.java
new file mode 100644
index 00000000000..c3d0b02f994
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/parser/AddressBookParserTest.java
@@ -0,0 +1,176 @@
+package hirehive.address.logic.parser;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.AddCommand;
+import hirehive.address.logic.commands.ClearCommand;
+import hirehive.address.logic.commands.DeleteCommand;
+import hirehive.address.logic.commands.DisplayNoteCommand;
+import hirehive.address.logic.commands.EditCommand;
+import hirehive.address.logic.commands.ExitCommand;
+import hirehive.address.logic.commands.FilterCommand;
+import hirehive.address.logic.commands.FilterOutCommand;
+import hirehive.address.logic.commands.FindCommand;
+import hirehive.address.logic.commands.HelpCommand;
+import hirehive.address.logic.commands.ListCommand;
+import hirehive.address.logic.commands.NewNoteCommand;
+import hirehive.address.logic.commands.ReminderCommand;
+import hirehive.address.logic.commands.ScheduleCommand;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.person.PersonContainsTagPredicate;
+import hirehive.address.model.person.PersonDoesNotContainTagPredicate;
+import hirehive.address.model.person.UpcomingInterviewPredicate;
+import hirehive.address.testutil.Assert;
+import hirehive.address.testutil.DefaultPersonBuilder;
+import hirehive.address.testutil.DefaultPersonUtil;
+import hirehive.address.testutil.EditPersonDescriptorBuilder;
+import hirehive.address.testutil.PersonBuilder;
+import hirehive.address.testutil.PersonUtil;
+import hirehive.address.testutil.TypicalIndexes;
+import hirehive.address.testutil.TypicalPersons;
+
+public class AddressBookParserTest {
+
+ private final AddressBookParser parser = new AddressBookParser();
+
+ @Test
+ public void parseCommand_add() throws Exception {
+ Person person = new DefaultPersonBuilder().build();
+ AddCommand command = (AddCommand) parser.parseCommand(DefaultPersonUtil.getAddCommand(person));
+ assertEquals(new AddCommand(person), command);
+ }
+
+ @Test
+ public void parseCommand_clear() throws Exception {
+ assertTrue(parser.parseCommand(ClearCommand.COMMAND_WORD) instanceof ClearCommand);
+ assertTrue(parser.parseCommand(ClearCommand.COMMAND_WORD + " 3") instanceof ClearCommand);
+ }
+
+ @Test
+ public void parseCommand_delete() throws Exception {
+ String nameToDelete = TypicalPersons.ALICE.getName().fullName;
+
+ DeleteCommand expectedCommand = new DeleteCommand(
+ new NameQuery(new NameContainsKeywordsPredicate(nameToDelete))
+ );
+ DeleteCommand command = (DeleteCommand) parser.parseCommand(
+ DeleteCommand.COMMAND_WORD + " " + "n/" + nameToDelete
+ );
+
+ assertEquals(expectedCommand, command);
+ }
+
+ @Test
+ public void parseCommand_edit() throws Exception {
+ Person person = new PersonBuilder().build();
+ EditCommand.EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(person).build();
+ EditCommand command = (EditCommand) parser.parseCommand(EditCommand.COMMAND_WORD + " "
+ + TypicalIndexes.INDEX_FIRST_PERSON.getOneBased() + " " + PersonUtil.getEditPersonDescriptorDetails(descriptor));
+ assertEquals(new EditCommand(TypicalIndexes.INDEX_FIRST_PERSON, descriptor), command);
+ }
+
+ @Test
+ public void parseCommand_exit() throws Exception {
+ assertTrue(parser.parseCommand(ExitCommand.COMMAND_WORD) instanceof ExitCommand);
+ assertTrue(parser.parseCommand(ExitCommand.COMMAND_WORD + " 3") instanceof ExitCommand);
+ }
+
+ @Test
+ public void parseCommand_find() throws Exception {
+ String keywords = "foo bar baz";
+ FindCommand command = (FindCommand) parser.parseCommand(
+ FindCommand.COMMAND_WORD + " " + keywords);
+ assertEquals(new FindCommand(new NameContainsKeywordsPredicate(keywords)), command);
+ }
+
+ @Test
+ public void parseCommand_filter() throws Exception {
+ String tag = "Applicant";
+ FilterCommand command = (FilterCommand) parser.parseCommand(FilterCommand.COMMAND_WORD + " t/ " + tag);
+ assertEquals(new FilterCommand(new PersonContainsTagPredicate(ParserUtil.parseTag(tag))), command);
+ }
+
+ @Test
+ public void parseCommand_remind() throws Exception {
+ String days = "5";
+ ReminderCommand command = (ReminderCommand) parser.parseCommand(ReminderCommand.COMMAND_WORD + " " + days);
+ assertEquals(new ReminderCommand(new UpcomingInterviewPredicate(5)), command);
+ }
+
+ @Test
+ public void parseCommand_help() throws Exception {
+ assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD) instanceof HelpCommand);
+ assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD + " 3") instanceof HelpCommand);
+ }
+
+ @Test
+ public void parseCommand_list() throws Exception {
+ assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD) instanceof ListCommand);
+ assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD + " 3") instanceof ListCommand);
+ }
+
+ @Test
+ public void parseCommand_note() throws Exception {
+ String nameToDisplay = TypicalPersons.ALICE.getName().fullName;
+
+ DisplayNoteCommand expectedCommand = new DisplayNoteCommand(nameToDisplay);
+ DisplayNoteCommand command = (DisplayNoteCommand) parser.parseCommand(
+ DisplayNoteCommand.COMMAND_WORD + " n/" + nameToDisplay
+ );
+
+ assertEquals(expectedCommand, command);
+ }
+
+ @Test
+ public void parseCommand_newnote() throws Exception {
+ String nameToAddNote = TypicalPersons.ALICE.getName().fullName;
+ EditCommand.EditPersonDescriptor editPersonDescriptor = new EditCommand.EditPersonDescriptor();
+ editPersonDescriptor.setNote(new Note("test"));
+
+ NewNoteCommand expectedCommand = new NewNoteCommand(nameToAddNote, editPersonDescriptor);
+ NewNoteCommand command = (NewNoteCommand) parser.parseCommand(
+ NewNoteCommand.COMMAND_WORD + " n/" + nameToAddNote + " i/test"
+ );
+
+ assertEquals(expectedCommand, command);
+ }
+
+ @Test
+ public void parseCommand_schedule() throws Exception {
+ String name = TypicalPersons.ALICE.getName().fullName;
+ EditCommand.EditPersonDescriptor editPersonDescriptor = new EditCommand.EditPersonDescriptor();
+ editPersonDescriptor.setDate(new InterviewDate("01/01/2026"));
+ ScheduleCommand expectedCommand = new ScheduleCommand(new NameQuery(new NameContainsKeywordsPredicate(name)), editPersonDescriptor);
+ ScheduleCommand parsedCommand = (ScheduleCommand) parser.parseCommand(ScheduleCommand.COMMAND_WORD + " "
+ + CliSyntax.PREFIX_NAME + name + " " + CliSyntax.PREFIX_DATE + "01/01/2026");
+ assertEquals(expectedCommand, parsedCommand);
+ }
+
+ @Test
+ public void parseCommand_filterout() throws Exception {
+ String tag = "Applicant";
+ FilterOutCommand command =
+ (FilterOutCommand) parser.parseCommand(FilterOutCommand.COMMAND_WORD + " t/ " + tag);
+ assertEquals(new FilterOutCommand(new PersonDoesNotContainTagPredicate(ParserUtil.parseTag(tag))), command);
+ }
+
+ @Test
+ public void parseCommand_unrecognisedInput_throwsParseException() {
+ Assert.assertThrows(ParseException.class, String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE), ()
+ -> parser.parseCommand(""));
+ }
+
+ @Test
+ public void parseCommand_unknownCommand_throwsParseException() {
+ Assert.assertThrows(ParseException.class, Messages.MESSAGE_UNKNOWN_COMMAND, () -> parser.parseCommand("unknownCommand"));
+ }
+}
diff --git a/src/test/java/seedu/address/logic/parser/ArgumentTokenizerTest.java b/src/test/java/hirehive/address/logic/parser/ArgumentTokenizerTest.java
similarity index 99%
rename from src/test/java/seedu/address/logic/parser/ArgumentTokenizerTest.java
rename to src/test/java/hirehive/address/logic/parser/ArgumentTokenizerTest.java
index c97308935f5..e981fe1201d 100644
--- a/src/test/java/seedu/address/logic/parser/ArgumentTokenizerTest.java
+++ b/src/test/java/hirehive/address/logic/parser/ArgumentTokenizerTest.java
@@ -1,4 +1,4 @@
-package seedu.address.logic.parser;
+package hirehive.address.logic.parser;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
diff --git a/src/test/java/seedu/address/logic/parser/CommandParserTestUtil.java b/src/test/java/hirehive/address/logic/parser/CommandParserTestUtil.java
similarity index 77%
rename from src/test/java/seedu/address/logic/parser/CommandParserTestUtil.java
rename to src/test/java/hirehive/address/logic/parser/CommandParserTestUtil.java
index 9bf1ccf1cef..cf0d3c4c790 100644
--- a/src/test/java/seedu/address/logic/parser/CommandParserTestUtil.java
+++ b/src/test/java/hirehive/address/logic/parser/CommandParserTestUtil.java
@@ -1,9 +1,11 @@
-package seedu.address.logic.parser;
+package hirehive.address.logic.parser;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import seedu.address.logic.commands.Command;
-import seedu.address.logic.parser.exceptions.ParseException;
+import org.junit.jupiter.api.Assertions;
+
+import hirehive.address.logic.commands.Command;
+import hirehive.address.logic.parser.exceptions.ParseException;
/**
* Contains helper methods for testing command parsers.
@@ -15,7 +17,7 @@ public class CommandParserTestUtil {
* equals to {@code expectedCommand}.
*/
public static void assertParseSuccess(Parser extends Command> parser, String userInput,
- Command expectedCommand) {
+ Command expectedCommand) {
try {
Command command = parser.parse(userInput);
assertEquals(expectedCommand, command);
@@ -33,7 +35,7 @@ public static void assertParseFailure(Parser extends Command> parser, String u
parser.parse(userInput);
throw new AssertionError("The expected ParseException was not thrown.");
} catch (ParseException pe) {
- assertEquals(expectedMessage, pe.getMessage());
+ Assertions.assertEquals(expectedMessage, pe.getMessage());
}
}
}
diff --git a/src/test/java/hirehive/address/logic/parser/DeleteCommandParserTest.java b/src/test/java/hirehive/address/logic/parser/DeleteCommandParserTest.java
new file mode 100644
index 00000000000..f090f28be9c
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/parser/DeleteCommandParserTest.java
@@ -0,0 +1,55 @@
+package hirehive.address.logic.parser;
+
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static hirehive.address.logic.parser.CommandParserTestUtil.assertParseSuccess;
+import static hirehive.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.DeleteCommand;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.testutil.TypicalIndexes;
+import hirehive.address.testutil.TypicalPersons;
+
+/**
+ * As we are only doing white-box testing, our test cases do not cover path variations
+ * outside of the DeleteCommand code. For example, inputs "1" and "1 abc" take the
+ * same path through the DeleteCommand, and therefore we test only one of them.
+ * The path variation for those two cases occur inside the ParserUtil, and
+ * therefore should be covered by the ParserUtilTest.
+ */
+public class DeleteCommandParserTest {
+
+ private DeleteCommandParser parser = new DeleteCommandParser();
+
+ @Test
+ public void parse_validArgs_returnsDeleteCommand() {
+ DeleteCommand expectedCommand = new DeleteCommand(
+ new NameQuery(new NameContainsKeywordsPredicate("Alice"))
+ );
+ assertParseSuccess(parser, " " + PREFIX_NAME + "Alice", expectedCommand);
+ }
+
+ @Test
+ public void parse_validArgsIndex_returnsDeleteCommand() {
+ assertParseSuccess(parser, "1", new DeleteCommand(INDEX_FIRST_PERSON));
+ }
+
+ @Test
+ public void parse_invalidArgs_throwsParseException() {
+ CommandParserTestUtil.assertParseFailure(parser, "",
+ String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE));
+ }
+
+ @Test
+ public void parse_indexAndNamePresent_throwsParseException() {
+ String userInput = "1 n/Alice";
+ CommandParserTestUtil.assertParseFailure(parser, userInput,
+ String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE));
+ }
+}
diff --git a/src/test/java/hirehive/address/logic/parser/DisplayNoteCommandParserTest.java b/src/test/java/hirehive/address/logic/parser/DisplayNoteCommandParserTest.java
new file mode 100644
index 00000000000..b90b12354de
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/parser/DisplayNoteCommandParserTest.java
@@ -0,0 +1,32 @@
+package hirehive.address.logic.parser;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.DisplayNoteCommand;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+
+public class DisplayNoteCommandParserTest {
+
+ private DisplayNoteCommandParser parser = new DisplayNoteCommandParser();
+
+ @Test
+ public void parse_validArgs_returnsNoteCommand() {
+ DisplayNoteCommand expectedCommand = new DisplayNoteCommand("Alice");
+
+ CommandParserTestUtil.assertParseSuccess(parser, "displaynote n/Alice", expectedCommand);
+ }
+
+ @Test
+ public void parse_invalidArgs_throwsParseException() {
+ CommandParserTestUtil.assertParseFailure(parser, "displaynote Alice",
+ String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, DisplayNoteCommand.MESSAGE_USAGE));
+ }
+
+ @Test
+ public void parse_duplicateArgs_throwsParseException() {
+ CommandParserTestUtil.assertParseFailure(parser, "note n/Alice n/Bob",
+ String.format(Messages.getErrorMessageForDuplicatePrefixes(new Prefix("n/"))));
+ }
+}
diff --git a/src/test/java/hirehive/address/logic/parser/EditCommandParserTest.java b/src/test/java/hirehive/address/logic/parser/EditCommandParserTest.java
new file mode 100644
index 00000000000..c767647ebc7
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/parser/EditCommandParserTest.java
@@ -0,0 +1,187 @@
+package hirehive.address.logic.parser;
+
+import static hirehive.address.logic.parser.CliSyntax.PREFIX_TAG;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.commons.util.StringUtil;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.CommandTestUtil;
+import hirehive.address.logic.commands.EditCommand;
+import hirehive.address.model.person.Address;
+import hirehive.address.model.person.Email;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.Name;
+import hirehive.address.model.person.Phone;
+import hirehive.address.model.tag.Tag;
+import hirehive.address.testutil.EditPersonDescriptorBuilder;
+import hirehive.address.testutil.TypicalIndexes;
+
+public class EditCommandParserTest {
+
+ private static final String TAG_EMPTY = " " + PREFIX_TAG;
+
+ private static final String MESSAGE_INVALID_FORMAT =
+ String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE);
+
+ private EditCommandParser parser = new EditCommandParser();
+
+ @Test
+ public void parse_missingParts_failure() {
+ // no index specified
+ CommandParserTestUtil.assertParseFailure(parser, CommandTestUtil.VALID_NAME_AMY, ParserUtil.MESSAGE_INVALID_INDEX);
+
+ // no field specified
+ CommandParserTestUtil.assertParseFailure(parser, "1", EditCommand.MESSAGE_NOT_EDITED);
+
+ // no index and no field specified
+ CommandParserTestUtil.assertParseFailure(parser, "", MESSAGE_INVALID_FORMAT);
+ }
+
+ @Test
+ public void parse_invalidPreamble_failure() {
+ // negative index
+ CommandParserTestUtil.assertParseFailure(parser, "-5" + CommandTestUtil.NAME_DESC_AMY, ParserUtil.MESSAGE_INVALID_INDEX);
+
+ // zero index
+ CommandParserTestUtil.assertParseFailure(parser, "0" + CommandTestUtil.NAME_DESC_AMY, ParserUtil.MESSAGE_INVALID_INDEX);
+
+ // invalid arguments being parsed as preamble
+ CommandParserTestUtil.assertParseFailure(parser, "1 some random string", ParserUtil.MESSAGE_INVALID_INDEX);
+
+ // invalid prefix being parsed as preamble
+ CommandParserTestUtil.assertParseFailure(parser, "1 z/ string", ParserUtil.MESSAGE_INVALID_INDEX);
+
+ // out of range integer
+ CommandParserTestUtil.assertParseFailure(parser, "100000000000000000000000000000 n/Alice", ParserUtil.MESSAGE_OUT_OF_RANGE);
+ }
+
+ @Test
+ public void parse_invalidValue_failure() {
+ CommandParserTestUtil.assertParseFailure(parser, "1" + CommandTestUtil.INVALID_NAME_DESC, Name.MESSAGE_CONSTRAINTS); // invalid name
+ CommandParserTestUtil.assertParseFailure(parser, "1" + CommandTestUtil.INVALID_PHONE_DESC, Phone.MESSAGE_CONSTRAINTS); // invalid phone
+ CommandParserTestUtil.assertParseFailure(parser, "1" + CommandTestUtil.INVALID_EMAIL_DESC, Email.MESSAGE_CONSTRAINTS); // invalid email
+ CommandParserTestUtil.assertParseFailure(parser, "1" + CommandTestUtil.INVALID_ADDRESS_DESC, Address.MESSAGE_CONSTRAINTS); // invalid address
+ CommandParserTestUtil.assertParseFailure(parser, "1" + CommandTestUtil.INVALID_TAG_DESC, Tag.MESSAGE_CONSTRAINTS); // invalid tag
+ CommandParserTestUtil.assertParseFailure(parser, "1" + CommandTestUtil.INVALID_DATE_DESC, InterviewDate.MESSAGE_CONSTRAINTS); // invalid date
+
+ // invalid phone followed by valid email
+ CommandParserTestUtil.assertParseFailure(parser, "1" + CommandTestUtil.INVALID_PHONE_DESC + CommandTestUtil.EMAIL_DESC_AMY, Phone.MESSAGE_CONSTRAINTS);
+
+ // while parsing {@code PREFIX_TAG} alone will reset the tags of the {@code Person} being edited,
+ // parsing it together with a valid tag results in error
+ CommandParserTestUtil.assertParseFailure(parser,
+ "1" + CommandTestUtil.TAG_DESC_APPLICANT + CommandTestUtil.TAG_DESC_CANDIDATE + TAG_EMPTY,
+ Messages.getErrorMessageForDuplicatePrefixes(PREFIX_TAG));
+ CommandParserTestUtil.assertParseFailure(parser,
+ "1" + CommandTestUtil.TAG_DESC_APPLICANT + TAG_EMPTY + CommandTestUtil.TAG_DESC_CANDIDATE,
+ Messages.getErrorMessageForDuplicatePrefixes(PREFIX_TAG));
+ CommandParserTestUtil.assertParseFailure(parser,
+ "1" + TAG_EMPTY + CommandTestUtil.TAG_DESC_APPLICANT + CommandTestUtil.TAG_DESC_CANDIDATE,
+ Messages.getErrorMessageForDuplicatePrefixes(PREFIX_TAG));
+
+ // multiple invalid values, but only the first invalid value is captured
+ CommandParserTestUtil.assertParseFailure(parser, "1" + CommandTestUtil.INVALID_NAME_DESC + CommandTestUtil.INVALID_EMAIL_DESC + CommandTestUtil.VALID_ADDRESS_AMY + CommandTestUtil.VALID_PHONE_AMY,
+ Name.MESSAGE_CONSTRAINTS);
+ }
+
+ @Test
+ public void parse_allFieldsSpecified_success() {
+ Index targetIndex = TypicalIndexes.INDEX_SECOND_PERSON;
+ String userInput = targetIndex.getOneBased() + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.EMAIL_DESC_AMY
+ + CommandTestUtil.ADDRESS_DESC_AMY + CommandTestUtil.NAME_DESC_AMY + CommandTestUtil.TAG_DESC_APPLICANT;
+
+ EditCommand.EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(CommandTestUtil.VALID_NAME_AMY)
+ .withPhone(CommandTestUtil.VALID_PHONE_BOB).withEmail(CommandTestUtil.VALID_EMAIL_AMY).withAddress(CommandTestUtil.VALID_ADDRESS_AMY)
+ .withTag(CommandTestUtil.VALID_TAG_APPLICANT).build();
+ EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
+
+ CommandParserTestUtil.assertParseSuccess(parser, userInput, expectedCommand);
+ }
+
+ @Test
+ public void parse_someFieldsSpecified_success() {
+ Index targetIndex = TypicalIndexes.INDEX_FIRST_PERSON;
+ String userInput = targetIndex.getOneBased() + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.EMAIL_DESC_AMY;
+
+ EditCommand.EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withPhone(CommandTestUtil.VALID_PHONE_BOB)
+ .withEmail(CommandTestUtil.VALID_EMAIL_AMY).build();
+ EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
+
+ CommandParserTestUtil.assertParseSuccess(parser, userInput, expectedCommand);
+ }
+
+ @Test
+ public void parse_oneFieldSpecified_success() {
+ // name
+ Index targetIndex = TypicalIndexes.INDEX_THIRD_PERSON;
+ String userInput = targetIndex.getOneBased() + CommandTestUtil.NAME_DESC_AMY;
+ EditCommand.EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(CommandTestUtil.VALID_NAME_AMY).build();
+ EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
+ CommandParserTestUtil.assertParseSuccess(parser, userInput, expectedCommand);
+
+ // phone
+ userInput = targetIndex.getOneBased() + CommandTestUtil.PHONE_DESC_AMY;
+ descriptor = new EditPersonDescriptorBuilder().withPhone(CommandTestUtil.VALID_PHONE_AMY).build();
+ expectedCommand = new EditCommand(targetIndex, descriptor);
+ CommandParserTestUtil.assertParseSuccess(parser, userInput, expectedCommand);
+
+ // email
+ userInput = targetIndex.getOneBased() + CommandTestUtil.EMAIL_DESC_AMY;
+ descriptor = new EditPersonDescriptorBuilder().withEmail(CommandTestUtil.VALID_EMAIL_AMY).build();
+ expectedCommand = new EditCommand(targetIndex, descriptor);
+ CommandParserTestUtil.assertParseSuccess(parser, userInput, expectedCommand);
+
+ // address
+ userInput = targetIndex.getOneBased() + CommandTestUtil.ADDRESS_DESC_AMY;
+ descriptor = new EditPersonDescriptorBuilder().withAddress(CommandTestUtil.VALID_ADDRESS_AMY).build();
+ expectedCommand = new EditCommand(targetIndex, descriptor);
+ CommandParserTestUtil.assertParseSuccess(parser, userInput, expectedCommand);
+
+ // tags
+ userInput = targetIndex.getOneBased() + CommandTestUtil.TAG_DESC_APPLICANT;
+ descriptor = new EditPersonDescriptorBuilder().withTag(CommandTestUtil.VALID_TAG_APPLICANT).build();
+ expectedCommand = new EditCommand(targetIndex, descriptor);
+ CommandParserTestUtil.assertParseSuccess(parser, userInput, expectedCommand);
+
+ // dates
+ userInput = targetIndex.getOneBased() + CommandTestUtil.DATE_DESC_BOB;
+ descriptor = new EditPersonDescriptorBuilder().withDate(CommandTestUtil.VALID_DATE_BOB).build();
+ expectedCommand = new EditCommand(targetIndex, descriptor);
+ CommandParserTestUtil.assertParseSuccess(parser, userInput, expectedCommand);
+ }
+
+ @Test
+ public void parse_multipleRepeatedFields_failure() {
+ // More extensive testing of duplicate parameter detections is done in
+ // AddCommandParserTest#parse_repeatedNonTagValue_failure()
+
+ // valid followed by invalid
+ Index targetIndex = TypicalIndexes.INDEX_FIRST_PERSON;
+ String userInput = targetIndex.getOneBased() + CommandTestUtil.INVALID_PHONE_DESC + CommandTestUtil.PHONE_DESC_BOB;
+
+ CommandParserTestUtil.assertParseFailure(parser, userInput, Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_PHONE));
+
+ // invalid followed by valid
+ userInput = targetIndex.getOneBased() + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.INVALID_PHONE_DESC;
+
+ CommandParserTestUtil.assertParseFailure(parser, userInput, Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_PHONE));
+
+ // mulltiple valid fields repeated
+ userInput = targetIndex.getOneBased() + CommandTestUtil.PHONE_DESC_AMY + CommandTestUtil.ADDRESS_DESC_AMY + CommandTestUtil.EMAIL_DESC_AMY
+ + CommandTestUtil.TAG_DESC_APPLICANT + CommandTestUtil.PHONE_DESC_AMY + CommandTestUtil.ADDRESS_DESC_AMY + CommandTestUtil.EMAIL_DESC_AMY + CommandTestUtil.TAG_DESC_APPLICANT
+ + CommandTestUtil.PHONE_DESC_BOB + CommandTestUtil.ADDRESS_DESC_BOB + CommandTestUtil.EMAIL_DESC_BOB + CommandTestUtil.TAG_DESC_CANDIDATE;
+
+ CommandParserTestUtil.assertParseFailure(parser, userInput,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_PHONE, CliSyntax.PREFIX_EMAIL,
+ CliSyntax.PREFIX_ADDRESS, PREFIX_TAG));
+
+ // multiple invalid values
+ userInput = targetIndex.getOneBased() + CommandTestUtil.INVALID_PHONE_DESC + CommandTestUtil.INVALID_ADDRESS_DESC + CommandTestUtil.INVALID_EMAIL_DESC
+ + CommandTestUtil.INVALID_PHONE_DESC + CommandTestUtil.INVALID_ADDRESS_DESC + CommandTestUtil.INVALID_EMAIL_DESC;
+
+ CommandParserTestUtil.assertParseFailure(parser, userInput,
+ Messages.getErrorMessageForDuplicatePrefixes(CliSyntax.PREFIX_PHONE, CliSyntax.PREFIX_EMAIL, CliSyntax.PREFIX_ADDRESS));
+ }
+}
diff --git a/src/test/java/hirehive/address/logic/parser/FilterCommandParserTest.java b/src/test/java/hirehive/address/logic/parser/FilterCommandParserTest.java
new file mode 100644
index 00000000000..66d3162910e
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/parser/FilterCommandParserTest.java
@@ -0,0 +1,25 @@
+package hirehive.address.logic.parser;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.FilterCommand;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.PersonContainsTagPredicate;
+import hirehive.address.model.tag.Tag;
+
+public class FilterCommandParserTest {
+ private FilterCommandParser parser = new FilterCommandParser();
+
+ @Test
+ public void parse_emptyArg_throwsParseException() {
+ CommandParserTestUtil.assertParseFailure(parser, " ", String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, FilterCommand.MESSAGE_USAGE));
+ }
+
+ @Test
+ public void parse_validArgs_returnsFilterCommand() throws ParseException {
+ FilterCommand expectedFilterCommand =
+ new FilterCommand(new PersonContainsTagPredicate(ParserUtil.parseTag("Applicant")));
+ CommandParserTestUtil.assertParseSuccess(parser, " t/ applicant", expectedFilterCommand);
+ }
+}
diff --git a/src/test/java/hirehive/address/logic/parser/FilterOutCommandParserTest.java b/src/test/java/hirehive/address/logic/parser/FilterOutCommandParserTest.java
new file mode 100644
index 00000000000..56f3a9eb025
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/parser/FilterOutCommandParserTest.java
@@ -0,0 +1,26 @@
+package hirehive.address.logic.parser;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.FilterOutCommand;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.PersonDoesNotContainTagPredicate;
+
+public class FilterOutCommandParserTest {
+ private FilterOutCommandParser parser = new FilterOutCommandParser();
+
+ @Test
+ public void parse_validArgs_returnsFilterOutCommand() throws ParseException {
+ PersonDoesNotContainTagPredicate predicate =
+ new PersonDoesNotContainTagPredicate(ParserUtil.parseTag("Candidate"));
+ FilterOutCommand expectedCommand = new FilterOutCommand(predicate);
+ CommandParserTestUtil.assertParseSuccess(parser, "filterout t/candidate", expectedCommand);
+ }
+
+ @Test
+ public void parse_invalidArgs_throwParseException() {
+ CommandParserTestUtil.assertParseFailure(parser, "",
+ String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, FilterOutCommand.MESSAGE_USAGE));
+ }
+}
diff --git a/src/test/java/hirehive/address/logic/parser/FindCommandParserTest.java b/src/test/java/hirehive/address/logic/parser/FindCommandParserTest.java
new file mode 100644
index 00000000000..5826f46b60f
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/parser/FindCommandParserTest.java
@@ -0,0 +1,31 @@
+package hirehive.address.logic.parser;
+
+import java.util.Arrays;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.FindCommand;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+
+public class FindCommandParserTest {
+
+ private FindCommandParser parser = new FindCommandParser();
+
+ @Test
+ public void parse_emptyArg_throwsParseException() {
+ CommandParserTestUtil.assertParseFailure(parser, " ", String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE));
+ }
+
+ @Test
+ public void parse_validArgs_returnsFindCommand() {
+ // no leading and trailing whitespaces
+ FindCommand expectedFindCommand =
+ new FindCommand(new NameContainsKeywordsPredicate("Alice Bob"));
+ CommandParserTestUtil.assertParseSuccess(parser, "Alice Bob", expectedFindCommand);
+
+ // with leading and trailing whitespaces
+ CommandParserTestUtil.assertParseSuccess(parser, " \n Alice Bob \t", expectedFindCommand);
+ }
+
+}
diff --git a/src/test/java/hirehive/address/logic/parser/NewNoteCommandParserTest.java b/src/test/java/hirehive/address/logic/parser/NewNoteCommandParserTest.java
new file mode 100644
index 00000000000..4e423ce7e91
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/parser/NewNoteCommandParserTest.java
@@ -0,0 +1,44 @@
+package hirehive.address.logic.parser;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.EditCommand;
+import hirehive.address.logic.commands.NewNoteCommand;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.model.person.Note;
+import hirehive.address.testutil.EditPersonDescriptorBuilder;
+import hirehive.address.testutil.TypicalPersons;
+
+public class NewNoteCommandParserTest {
+
+ private NewNoteCommandParser parser = new NewNoteCommandParser();
+
+ @Test
+ public void parse_validArgs_returnsNewNoteCommand() {
+ EditCommand.EditPersonDescriptor editPersonDescriptor = new EditCommand.EditPersonDescriptor();
+ editPersonDescriptor.setNote(new Note("test"));
+ NewNoteCommand expectedCommand = new NewNoteCommand("Alice", editPersonDescriptor);
+
+ CommandParserTestUtil.assertParseSuccess(parser, "newnote n/Alice i/test", expectedCommand);
+ }
+
+ @Test
+ public void parse_invalidArgs_throwsParseException() {
+ CommandParserTestUtil.assertParseFailure(parser, "newnote Alice i/test",
+ String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, NewNoteCommand.MESSAGE_USAGE));
+ }
+
+ @Test
+ public void parse_noName_throwsParseException() {
+ CommandParserTestUtil.assertParseFailure(parser, "newnote i/test",
+ String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, NewNoteCommand.MESSAGE_USAGE));
+ }
+
+ @Test
+ public void parse_noNote_throwsParseException() {
+ CommandParserTestUtil.assertParseFailure(parser, "newnote n/Alice",
+ String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, NewNoteCommand.MESSAGE_USAGE));
+ }
+}
diff --git a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java b/src/test/java/hirehive/address/logic/parser/ParserUtilTest.java
similarity index 57%
rename from src/test/java/seedu/address/logic/parser/ParserUtilTest.java
rename to src/test/java/hirehive/address/logic/parser/ParserUtilTest.java
index 4256788b1a7..2260d84e185 100644
--- a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java
+++ b/src/test/java/hirehive/address/logic/parser/ParserUtilTest.java
@@ -1,69 +1,83 @@
-package seedu.address.logic.parser;
+package hirehive.address.logic.parser;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.parser.ParserUtil.MESSAGE_INVALID_INDEX;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.Address;
+import hirehive.address.model.person.Email;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.Name;
+import hirehive.address.model.person.Phone;
+import hirehive.address.model.tag.Tag;
+import hirehive.address.testutil.Assert;
+import hirehive.address.testutil.TypicalIndexes;
public class ParserUtilTest {
- private static final String INVALID_NAME = "R@chel";
+ private static final String INVALID_NAME = "R4chel";
+ private static final String INVALID_NAME_2 = ".Rachel";
private static final String INVALID_PHONE = "+651234";
private static final String INVALID_ADDRESS = " ";
private static final String INVALID_EMAIL = "example.com";
private static final String INVALID_TAG = "#friend";
-
+ private static final String INVALID_DATE = "01012004";
private static final String VALID_NAME = "Rachel Walker";
- private static final String VALID_PHONE = "123456";
+ private static final String VALID_NAME_2 = "R@c/hel, Wa()l-ker.";
+ private static final String VALID_PHONE = "91234467";
private static final String VALID_ADDRESS = "123 Main Street #0505";
private static final String VALID_EMAIL = "rachel@example.com";
- private static final String VALID_TAG_1 = "friend";
- private static final String VALID_TAG_2 = "neighbour";
-
+ private static final String VALID_TAG_1 = "Applicant";
+ private static final String VALID_TAG_2 = "Candidate";
+ private static final String VALID_DATE = "01/01/2004";
private static final String WHITESPACE = " \t\r\n";
@Test
public void parseIndex_invalidInput_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parseIndex("10 a"));
+ Assert.assertThrows(ParseException.class, () -> ParserUtil.parseIndex("10 a"));
}
@Test
public void parseIndex_outOfRangeInput_throwsParseException() {
- assertThrows(ParseException.class, MESSAGE_INVALID_INDEX, ()
+ Assert.assertThrows(ParseException.class, ParserUtil.MESSAGE_INVALID_INDEX, ()
-> ParserUtil.parseIndex(Long.toString(Integer.MAX_VALUE + 1)));
}
@Test
public void parseIndex_validInput_success() throws Exception {
// No whitespaces
- assertEquals(INDEX_FIRST_PERSON, ParserUtil.parseIndex("1"));
+ Assertions.assertEquals(TypicalIndexes.INDEX_FIRST_PERSON, ParserUtil.parseIndex("1"));
// Leading and trailing whitespaces
- assertEquals(INDEX_FIRST_PERSON, ParserUtil.parseIndex(" 1 "));
+ Assertions.assertEquals(TypicalIndexes.INDEX_FIRST_PERSON, ParserUtil.parseIndex(" 1 "));
}
@Test
public void parseName_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> ParserUtil.parseName((String) null));
+ Assert.assertThrows(NullPointerException.class, () -> ParserUtil.parseName((String) null));
+ }
+
+ @Test
+ public void parseName_number_throwsParseException() {
+ Assert.assertThrows(ParseException.class, () -> ParserUtil.parseName(INVALID_NAME));
}
@Test
public void parseName_invalidValue_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parseName(INVALID_NAME));
+ Assert.assertThrows(ParseException.class, () -> ParserUtil.parseName(INVALID_NAME_2));
+ }
+
+ @Test
+ public void parseName_validValueWithCommercialAt() throws Exception {
+ Name expectedName = new Name(VALID_NAME_2);
+ assertEquals(expectedName, ParserUtil.parseName(VALID_NAME_2));
}
@Test
@@ -81,12 +95,12 @@ public void parseName_validValueWithWhitespace_returnsTrimmedName() throws Excep
@Test
public void parsePhone_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> ParserUtil.parsePhone((String) null));
+ Assert.assertThrows(NullPointerException.class, () -> ParserUtil.parsePhone((String) null));
}
@Test
public void parsePhone_invalidValue_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parsePhone(INVALID_PHONE));
+ Assert.assertThrows(ParseException.class, () -> ParserUtil.parsePhone(INVALID_PHONE));
}
@Test
@@ -104,12 +118,12 @@ public void parsePhone_validValueWithWhitespace_returnsTrimmedPhone() throws Exc
@Test
public void parseAddress_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> ParserUtil.parseAddress((String) null));
+ Assert.assertThrows(NullPointerException.class, () -> ParserUtil.parseAddress((String) null));
}
@Test
public void parseAddress_invalidValue_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parseAddress(INVALID_ADDRESS));
+ Assert.assertThrows(ParseException.class, () -> ParserUtil.parseAddress(INVALID_ADDRESS));
}
@Test
@@ -127,12 +141,12 @@ public void parseAddress_validValueWithWhitespace_returnsTrimmedAddress() throws
@Test
public void parseEmail_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> ParserUtil.parseEmail((String) null));
+ Assert.assertThrows(NullPointerException.class, () -> ParserUtil.parseEmail((String) null));
}
@Test
public void parseEmail_invalidValue_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parseEmail(INVALID_EMAIL));
+ Assert.assertThrows(ParseException.class, () -> ParserUtil.parseEmail(INVALID_EMAIL));
}
@Test
@@ -150,35 +164,35 @@ public void parseEmail_validValueWithWhitespace_returnsTrimmedEmail() throws Exc
@Test
public void parseTag_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> ParserUtil.parseTag(null));
+ Assert.assertThrows(NullPointerException.class, () -> ParserUtil.parseTag(null));
}
@Test
public void parseTag_invalidValue_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parseTag(INVALID_TAG));
+ Assert.assertThrows(ParseException.class, () -> ParserUtil.parseTag(INVALID_TAG));
}
@Test
public void parseTag_validValueWithoutWhitespace_returnsTag() throws Exception {
- Tag expectedTag = new Tag(VALID_TAG_1);
+ Tag expectedTag = Tag.APPLICANT;
assertEquals(expectedTag, ParserUtil.parseTag(VALID_TAG_1));
}
@Test
public void parseTag_validValueWithWhitespace_returnsTrimmedTag() throws Exception {
String tagWithWhitespace = WHITESPACE + VALID_TAG_1 + WHITESPACE;
- Tag expectedTag = new Tag(VALID_TAG_1);
+ Tag expectedTag = Tag.APPLICANT;
assertEquals(expectedTag, ParserUtil.parseTag(tagWithWhitespace));
}
@Test
public void parseTags_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> ParserUtil.parseTags(null));
+ Assert.assertThrows(NullPointerException.class, () -> ParserUtil.parseTags(null));
}
@Test
public void parseTags_collectionWithInvalidTags_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parseTags(Arrays.asList(VALID_TAG_1, INVALID_TAG)));
+ Assert.assertThrows(ParseException.class, () -> ParserUtil.parseTags(Arrays.asList(VALID_TAG_1, INVALID_TAG)));
}
@Test
@@ -188,9 +202,35 @@ public void parseTags_emptyCollection_returnsEmptySet() throws Exception {
@Test
public void parseTags_collectionWithValidTags_returnsTagSet() throws Exception {
+ // VALID_TAG_1 = "Applicant", VALID_TAG_2 = "Candidate"
Set actualTagSet = ParserUtil.parseTags(Arrays.asList(VALID_TAG_1, VALID_TAG_2));
- Set expectedTagSet = new HashSet(Arrays.asList(new Tag(VALID_TAG_1), new Tag(VALID_TAG_2)));
+ Set expectedTagSet = new HashSet(Arrays.asList(Tag.APPLICANT, Tag.CANDIDATE));
assertEquals(expectedTagSet, actualTagSet);
}
+
+ @Test
+ public void parseDate_null_throwsNullPointerException() {
+ Assert.assertThrows(NullPointerException.class, () -> ParserUtil.parseDate(null));
+ }
+
+ @Test
+ public void parseDate_validValueWithoutWhitespace_returnsDate() throws Exception {
+ InterviewDate expectedDate = new InterviewDate(VALID_DATE);
+ assertEquals(expectedDate, ParserUtil.parseDate(VALID_DATE));
+ }
+
+ @Test
+ public void parseDate_validValueWithWhitespace_returnsTrimmedDate() throws Exception {
+ String dateWithWhiteSpace = WHITESPACE + VALID_DATE + WHITESPACE;
+ InterviewDate expectedDate = new InterviewDate(VALID_DATE);
+ assertEquals(expectedDate, ParserUtil.parseDate(dateWithWhiteSpace));
+ }
+
+ @Test
+ public void parseDate_invalidValue_throwsParseException() {
+ Assert.assertThrows(ParseException.class, () -> ParserUtil.parseDate(INVALID_DATE));
+ }
+
+
}
diff --git a/src/test/java/hirehive/address/logic/parser/ReminderCommandParserTest.java b/src/test/java/hirehive/address/logic/parser/ReminderCommandParserTest.java
new file mode 100644
index 00000000000..fecbedf259b
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/parser/ReminderCommandParserTest.java
@@ -0,0 +1,27 @@
+package hirehive.address.logic.parser;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.FilterCommand;
+import hirehive.address.logic.commands.ReminderCommand;
+import hirehive.address.model.person.PersonContainsTagPredicate;
+import hirehive.address.model.person.UpcomingInterviewPredicate;
+import hirehive.address.model.tag.Tag;
+
+public class ReminderCommandParserTest {
+ private ReminderCommandParser parser = new ReminderCommandParser();
+
+ @Test
+ public void parse_emptyArg_throwsParseException() {
+ CommandParserTestUtil.assertParseFailure(parser, " ", String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, ReminderCommand.MESSAGE_USAGE));
+ CommandParserTestUtil.assertParseFailure(parser, "100000000000000000000000000000000", ParserUtil.MESSAGE_OUT_OF_RANGE);
+ }
+
+ @Test
+ public void parse_validArgs_returnsReminderCommand() {
+ ReminderCommand expectedReminderCommand =
+ new ReminderCommand(new UpcomingInterviewPredicate(10));
+ CommandParserTestUtil.assertParseSuccess(parser, " 10", expectedReminderCommand);
+ }
+}
diff --git a/src/test/java/hirehive/address/logic/parser/ScheduleCommandParserTest.java b/src/test/java/hirehive/address/logic/parser/ScheduleCommandParserTest.java
new file mode 100644
index 00000000000..f1db7d953a3
--- /dev/null
+++ b/src/test/java/hirehive/address/logic/parser/ScheduleCommandParserTest.java
@@ -0,0 +1,45 @@
+package hirehive.address.logic.parser;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.commands.EditCommand;
+import hirehive.address.logic.commands.ReminderCommand;
+import hirehive.address.logic.commands.ScheduleCommand;
+import hirehive.address.logic.commands.queries.NameQuery;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.model.person.Note;
+import hirehive.address.testutil.EditPersonDescriptorBuilder;
+
+public class ScheduleCommandParserTest {
+ private ScheduleCommandParser parser = new ScheduleCommandParser();
+
+ @Test
+ public void parse_emptyArg_throwsParseException() {
+ CommandParserTestUtil.assertParseFailure(parser, " ", String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, ScheduleCommand.MESSAGE_USAGE));
+ }
+
+ @Test
+ public void parse_invalidDate_throwsParseException() {
+ CommandParserTestUtil.assertParseFailure(parser, " n/Alice id/01/01/1500", ScheduleCommandParser.MESSAGE_DATE_OUT_OF_BOUNDS);
+ }
+
+ @Test
+ public void parse_validArgs_returnsScheduleCommand() {
+ EditCommand.EditPersonDescriptor editPersonDescriptor = new EditCommand.EditPersonDescriptor();
+ editPersonDescriptor.setDate(new InterviewDate("31/12/2999"));
+ ScheduleCommand expectedScheduleCommand = new ScheduleCommand(new NameQuery(new NameContainsKeywordsPredicate("Alice")), editPersonDescriptor);
+ CommandParserTestUtil.assertParseSuccess(parser, " n/Alice id/31/12/2999", expectedScheduleCommand);
+
+ expectedScheduleCommand = new ScheduleCommand(Index.fromOneBased(1), editPersonDescriptor);
+ CommandParserTestUtil.assertParseSuccess(parser, "1 id/31/12/2999", expectedScheduleCommand);
+
+ expectedScheduleCommand = new ScheduleCommand(new NameQuery(new NameContainsKeywordsPredicate("Alice")));
+ CommandParserTestUtil.assertParseSuccess(parser, " n/Alice", expectedScheduleCommand);
+
+ expectedScheduleCommand = new ScheduleCommand(Index.fromOneBased(1));
+ CommandParserTestUtil.assertParseSuccess(parser, "1", expectedScheduleCommand);
+ }
+}
diff --git a/src/test/java/seedu/address/model/AddressBookTest.java b/src/test/java/hirehive/address/model/AddressBookTest.java
similarity index 60%
rename from src/test/java/seedu/address/model/AddressBookTest.java
rename to src/test/java/hirehive/address/model/AddressBookTest.java
index 68c8c5ba4d5..3b2cdc31aee 100644
--- a/src/test/java/seedu/address/model/AddressBookTest.java
+++ b/src/test/java/hirehive/address/model/AddressBookTest.java
@@ -1,13 +1,11 @@
-package seedu.address.model;
+package hirehive.address.model;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_TAG_CANDIDATE;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
import java.util.Arrays;
import java.util.Collection;
@@ -16,11 +14,13 @@
import org.junit.jupiter.api.Test;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.person.exceptions.DuplicatePersonException;
+import hirehive.address.testutil.Assert;
+import hirehive.address.testutil.PersonBuilder;
+import hirehive.address.testutil.TypicalPersons;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.exceptions.DuplicatePersonException;
-import seedu.address.testutil.PersonBuilder;
public class AddressBookTest {
@@ -33,12 +33,12 @@ public void constructor() {
@Test
public void resetData_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> addressBook.resetData(null));
+ Assert.assertThrows(NullPointerException.class, () -> addressBook.resetData(null));
}
@Test
public void resetData_withValidReadOnlyAddressBook_replacesData() {
- AddressBook newData = getTypicalAddressBook();
+ AddressBook newData = TypicalPersons.getTypicalAddressBook();
addressBook.resetData(newData);
assertEquals(newData, addressBook);
}
@@ -46,41 +46,41 @@ public void resetData_withValidReadOnlyAddressBook_replacesData() {
@Test
public void resetData_withDuplicatePersons_throwsDuplicatePersonException() {
// Two persons with the same identity fields
- Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND)
+ Person editedAlice = new PersonBuilder(TypicalPersons.ALICE).withAddress(VALID_ADDRESS_BOB).withTag(VALID_TAG_CANDIDATE)
.build();
- List newPersons = Arrays.asList(ALICE, editedAlice);
+ List newPersons = Arrays.asList(TypicalPersons.ALICE, editedAlice);
AddressBookStub newData = new AddressBookStub(newPersons);
- assertThrows(DuplicatePersonException.class, () -> addressBook.resetData(newData));
+ Assert.assertThrows(DuplicatePersonException.class, () -> addressBook.resetData(newData));
}
@Test
public void hasPerson_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> addressBook.hasPerson(null));
+ Assert.assertThrows(NullPointerException.class, () -> addressBook.hasPerson(null));
}
@Test
public void hasPerson_personNotInAddressBook_returnsFalse() {
- assertFalse(addressBook.hasPerson(ALICE));
+ assertFalse(addressBook.hasPerson(TypicalPersons.ALICE));
}
@Test
public void hasPerson_personInAddressBook_returnsTrue() {
- addressBook.addPerson(ALICE);
- assertTrue(addressBook.hasPerson(ALICE));
+ addressBook.addPerson(TypicalPersons.ALICE);
+ assertTrue(addressBook.hasPerson(TypicalPersons.ALICE));
}
@Test
public void hasPerson_personWithSameIdentityFieldsInAddressBook_returnsTrue() {
- addressBook.addPerson(ALICE);
- Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND)
+ addressBook.addPerson(TypicalPersons.ALICE);
+ Person editedAlice = new PersonBuilder(TypicalPersons.ALICE).withAddress(VALID_ADDRESS_BOB).withTag(VALID_TAG_CANDIDATE)
.build();
assertTrue(addressBook.hasPerson(editedAlice));
}
@Test
public void getPersonList_modifyList_throwsUnsupportedOperationException() {
- assertThrows(UnsupportedOperationException.class, () -> addressBook.getPersonList().remove(0));
+ Assert.assertThrows(UnsupportedOperationException.class, () -> addressBook.getPersonList().remove(0));
}
@Test
diff --git a/src/test/java/seedu/address/model/ModelManagerTest.java b/src/test/java/hirehive/address/model/ModelManagerTest.java
similarity index 50%
rename from src/test/java/seedu/address/model/ModelManagerTest.java
rename to src/test/java/hirehive/address/model/ModelManagerTest.java
index 2cf1418d116..94baf0e04c5 100644
--- a/src/test/java/seedu/address/model/ModelManagerTest.java
+++ b/src/test/java/hirehive/address/model/ModelManagerTest.java
@@ -1,22 +1,31 @@
-package seedu.address.model;
+package hirehive.address.model;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.BENSON;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.ResolverStyle;
import java.util.Arrays;
+import java.util.List;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
-import seedu.address.testutil.AddressBookBuilder;
+import hirehive.address.commons.core.GuiSettings;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.NameContainsKeywordsPredicate;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
+import hirehive.address.testutil.AddressBookBuilder;
+import hirehive.address.testutil.Assert;
+import hirehive.address.testutil.TypicalPersons;
public class ModelManagerTest {
@@ -25,13 +34,13 @@ public class ModelManagerTest {
@Test
public void constructor() {
assertEquals(new UserPrefs(), modelManager.getUserPrefs());
- assertEquals(new GuiSettings(), modelManager.getGuiSettings());
+ Assertions.assertEquals(new GuiSettings(), modelManager.getGuiSettings());
assertEquals(new AddressBook(), new AddressBook(modelManager.getAddressBook()));
}
@Test
public void setUserPrefs_nullUserPrefs_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> modelManager.setUserPrefs(null));
+ Assert.assertThrows(NullPointerException.class, () -> modelManager.setUserPrefs(null));
}
@Test
@@ -50,7 +59,7 @@ public void setUserPrefs_validUserPrefs_copiesUserPrefs() {
@Test
public void setGuiSettings_nullGuiSettings_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> modelManager.setGuiSettings(null));
+ Assert.assertThrows(NullPointerException.class, () -> modelManager.setGuiSettings(null));
}
@Test
@@ -62,7 +71,7 @@ public void setGuiSettings_validGuiSettings_setsGuiSettings() {
@Test
public void setAddressBookFilePath_nullPath_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> modelManager.setAddressBookFilePath(null));
+ Assert.assertThrows(NullPointerException.class, () -> modelManager.setAddressBookFilePath(null));
}
@Test
@@ -74,28 +83,84 @@ public void setAddressBookFilePath_validPath_setsAddressBookFilePath() {
@Test
public void hasPerson_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> modelManager.hasPerson(null));
+ Assert.assertThrows(NullPointerException.class, () -> modelManager.hasPerson(null));
}
@Test
public void hasPerson_personNotInAddressBook_returnsFalse() {
- assertFalse(modelManager.hasPerson(ALICE));
+ assertFalse(modelManager.hasPerson(TypicalPersons.ALICE));
}
@Test
public void hasPerson_personInAddressBook_returnsTrue() {
- modelManager.addPerson(ALICE);
- assertTrue(modelManager.hasPerson(ALICE));
+ modelManager.addPerson(TypicalPersons.ALICE);
+ assertTrue(modelManager.hasPerson(TypicalPersons.ALICE));
}
@Test
public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException() {
- assertThrows(UnsupportedOperationException.class, () -> modelManager.getFilteredPersonList().remove(0));
+ Assert.assertThrows(UnsupportedOperationException.class, () -> modelManager.getFilteredPersonList().remove(0));
+ }
+
+ @Test
+ public void sortPersons_sortsApplicantsByInterviewDate() {
+ modelManager.addPerson(TypicalPersons.ELLE);
+ modelManager.addPerson(TypicalPersons.BENSON);
+
+ List originalList = List.copyOf(modelManager.getFilteredPersonList());
+
+ modelManager.sortPersons();
+
+ List sortedList = modelManager.getFilteredPersonList();
+
+ assertNotEquals(originalList, sortedList);
+ assertTrue(sortedList.get(0).getDate().getValue().orElse(LocalDate.MAX)
+ .isBefore(sortedList.get(1).getDate().getValue().orElse(LocalDate.MAX)));
+ }
+
+
+ @Test
+ public void resetSorting_revertsToOriginalOrder() {
+ modelManager.addPerson(TypicalPersons.BENSON);
+ modelManager.addPerson(TypicalPersons.ELLE);
+
+ List originalList = List.copyOf(modelManager.getFilteredPersonList());
+
+ modelManager.sortPersons();
+ modelManager.resetSorting();
+
+ List resetList = modelManager.getFilteredPersonList();
+
+ assertEquals(originalList, resetList);
+ }
+
+ @Test
+ public void getPersonNote_initial_returnsDefaultNote() {
+ assertEquals(modelManager.getPersonNote(), new Note(Note.DEFAULT_NOTE));
+ }
+
+ @Test
+ public void getPersonNote_person_getPersonNote() {
+ modelManager.updatePersonNote(TypicalPersons.ALICE);
+ assertEquals(modelManager.getPersonNote(), TypicalPersons.ALICE.getNote());
+ }
+
+ @Test
+ public void getListSize_initialList_returnListSize() {
+ int listSize = modelManager.getListSize();
+ assertEquals(listSize, modelManager.getFilteredPersonList().size());
+ }
+
+ @Test
+ public void getAvailableDate_initialList_returnAvailableDate() {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu")
+ .withResolverStyle(ResolverStyle.STRICT);
+ assertEquals(modelManager.getAvailableDate(), new InterviewDate(LocalDate.now().plusDays(1).format(formatter)));
}
@Test
public void equals() {
- AddressBook addressBook = new AddressBookBuilder().withPerson(ALICE).withPerson(BENSON).build();
+ AddressBook addressBook = new AddressBookBuilder().withPerson(TypicalPersons.ALICE).withPerson(TypicalPersons.BENSON).build();
AddressBook differentAddressBook = new AddressBook();
UserPrefs userPrefs = new UserPrefs();
@@ -117,12 +182,12 @@ public void equals() {
assertFalse(modelManager.equals(new ModelManager(differentAddressBook, userPrefs)));
// different filteredList -> returns false
- String[] keywords = ALICE.getName().fullName.split("\\s+");
- modelManager.updateFilteredPersonList(new NameContainsKeywordsPredicate(Arrays.asList(keywords)));
+ String keywords = TypicalPersons.ALICE.getName().fullName;
+ modelManager.updateFilteredPersonList(new NameContainsKeywordsPredicate(keywords));
assertFalse(modelManager.equals(new ModelManager(addressBook, userPrefs)));
// resets modelManager to initial state for upcoming tests
- modelManager.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
+ modelManager.updateFilteredPersonList(Model.PREDICATE_SHOW_ALL_PERSONS);
// different userPrefs -> returns false
UserPrefs differentUserPrefs = new UserPrefs();
diff --git a/src/test/java/seedu/address/model/UserPrefsTest.java b/src/test/java/hirehive/address/model/UserPrefsTest.java
similarity index 51%
rename from src/test/java/seedu/address/model/UserPrefsTest.java
rename to src/test/java/hirehive/address/model/UserPrefsTest.java
index b1307a70d52..f42c28d8952 100644
--- a/src/test/java/seedu/address/model/UserPrefsTest.java
+++ b/src/test/java/hirehive/address/model/UserPrefsTest.java
@@ -1,21 +1,23 @@
-package seedu.address.model;
+package hirehive.address.model;
-import static seedu.address.testutil.Assert.assertThrows;
+import static hirehive.address.testutil.Assert.assertThrows;
import org.junit.jupiter.api.Test;
+import hirehive.address.testutil.Assert;
+
public class UserPrefsTest {
@Test
public void setGuiSettings_nullGuiSettings_throwsNullPointerException() {
UserPrefs userPref = new UserPrefs();
- assertThrows(NullPointerException.class, () -> userPref.setGuiSettings(null));
+ Assert.assertThrows(NullPointerException.class, () -> userPref.setGuiSettings(null));
}
@Test
public void setAddressBookFilePath_nullPath_throwsNullPointerException() {
UserPrefs userPrefs = new UserPrefs();
- assertThrows(NullPointerException.class, () -> userPrefs.setAddressBookFilePath(null));
+ Assert.assertThrows(NullPointerException.class, () -> userPrefs.setAddressBookFilePath(null));
}
}
diff --git a/src/test/java/seedu/address/model/person/AddressTest.java b/src/test/java/hirehive/address/model/person/AddressTest.java
similarity index 78%
rename from src/test/java/seedu/address/model/person/AddressTest.java
rename to src/test/java/hirehive/address/model/person/AddressTest.java
index 314885eca26..244e0dbe915 100644
--- a/src/test/java/seedu/address/model/person/AddressTest.java
+++ b/src/test/java/hirehive/address/model/person/AddressTest.java
@@ -1,28 +1,30 @@
-package seedu.address.model.person;
+package hirehive.address.model.person;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
import org.junit.jupiter.api.Test;
+import hirehive.address.testutil.Assert;
+
public class AddressTest {
@Test
public void constructor_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> new Address(null));
+ Assert.assertThrows(NullPointerException.class, () -> new Address(null));
}
@Test
public void constructor_invalidAddress_throwsIllegalArgumentException() {
String invalidAddress = "";
- assertThrows(IllegalArgumentException.class, () -> new Address(invalidAddress));
+ Assert.assertThrows(IllegalArgumentException.class, () -> new Address(invalidAddress));
}
@Test
public void isValidAddress() {
// null address
- assertThrows(NullPointerException.class, () -> Address.isValidAddress(null));
+ Assert.assertThrows(NullPointerException.class, () -> Address.isValidAddress(null));
// invalid addresses
assertFalse(Address.isValidAddress("")); // empty string
diff --git a/src/test/java/seedu/address/model/person/EmailTest.java b/src/test/java/hirehive/address/model/person/EmailTest.java
similarity index 91%
rename from src/test/java/seedu/address/model/person/EmailTest.java
rename to src/test/java/hirehive/address/model/person/EmailTest.java
index f08cdff0a64..a0259e86293 100644
--- a/src/test/java/seedu/address/model/person/EmailTest.java
+++ b/src/test/java/hirehive/address/model/person/EmailTest.java
@@ -1,28 +1,30 @@
-package seedu.address.model.person;
+package hirehive.address.model.person;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
import org.junit.jupiter.api.Test;
+import hirehive.address.testutil.Assert;
+
public class EmailTest {
@Test
public void constructor_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> new Email(null));
+ Assert.assertThrows(NullPointerException.class, () -> new Email(null));
}
@Test
public void constructor_invalidEmail_throwsIllegalArgumentException() {
String invalidEmail = "";
- assertThrows(IllegalArgumentException.class, () -> new Email(invalidEmail));
+ Assert.assertThrows(IllegalArgumentException.class, () -> new Email(invalidEmail));
}
@Test
public void isValidEmail() {
// null email
- assertThrows(NullPointerException.class, () -> Email.isValidEmail(null));
+ Assert.assertThrows(NullPointerException.class, () -> Email.isValidEmail(null));
// blank email
assertFalse(Email.isValidEmail("")); // empty string
diff --git a/src/test/java/hirehive/address/model/person/InterviewDateTest.java b/src/test/java/hirehive/address/model/person/InterviewDateTest.java
new file mode 100644
index 00000000000..71aafb6a80a
--- /dev/null
+++ b/src/test/java/hirehive/address/model/person/InterviewDateTest.java
@@ -0,0 +1,58 @@
+package hirehive.address.model.person;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.testutil.Assert;
+
+public class InterviewDateTest {
+
+ @Test
+ public void constructor_null_throwsNullPointerException() {
+ Assert.assertThrows(NullPointerException.class, () -> new InterviewDate(null));
+ }
+
+ @Test
+ public void constructor_invalidDate_throwsIllegalArgumentException() {
+ String invalidDate = "01-01-2004";
+ Assert.assertThrows(IllegalArgumentException.class, () -> new InterviewDate(invalidDate));
+ }
+
+ @Test
+ public void isValidDate() {
+ // null date
+ Assert.assertThrows(NullPointerException.class, () -> InterviewDate.isValidDate(null));
+
+ // invalid date
+ assertFalse(InterviewDate.isValidDate(" ")); // spaces only
+ assertFalse(InterviewDate.isValidDate("abcde12345")); // only alphanumeric characters
+ assertFalse(InterviewDate.isValidDate("01022004")); // no / separators
+ assertFalse(InterviewDate.isValidDate("01-02-2004")); // wrong separators
+ // valid date
+ assertTrue(InterviewDate.isValidDate("01/02/2004"));
+ // empty string
+ assertTrue(InterviewDate.isValidDate(""));
+ }
+
+ @Test
+ public void equals() {
+ InterviewDate date = new InterviewDate("01/01/2025");
+
+ // same values -> returns true
+ assertTrue(date.equals(new InterviewDate("01/01/2025")));
+
+ // same object -> returns true
+ assertTrue(date.equals(date));
+
+ // null -> returns false
+ assertFalse(date.equals(null));
+
+ // different types -> returns false
+ assertFalse(date.equals(5.0f));
+
+ // different values -> returns false
+ assertFalse(date.equals(new InterviewDate("01/02/2025")));
+ }
+}
diff --git a/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java b/src/test/java/hirehive/address/model/person/NameContainsKeywordsPredicateTest.java
similarity index 63%
rename from src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java
rename to src/test/java/hirehive/address/model/person/NameContainsKeywordsPredicateTest.java
index 6b3fd90ade7..b522c5c0114 100644
--- a/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java
+++ b/src/test/java/hirehive/address/model/person/NameContainsKeywordsPredicateTest.java
@@ -1,4 +1,4 @@
-package seedu.address.model.person;
+package hirehive.address.model.person;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -10,23 +10,24 @@
import org.junit.jupiter.api.Test;
-import seedu.address.testutil.PersonBuilder;
+import hirehive.address.logic.Messages;
+import hirehive.address.testutil.PersonBuilder;
public class NameContainsKeywordsPredicateTest {
@Test
public void equals() {
- List firstPredicateKeywordList = Collections.singletonList("first");
- List secondPredicateKeywordList = Arrays.asList("first", "second");
+ String firstPredicateKeyword = "first";
+ String secondPredicateKeyword = "first second";
- NameContainsKeywordsPredicate firstPredicate = new NameContainsKeywordsPredicate(firstPredicateKeywordList);
- NameContainsKeywordsPredicate secondPredicate = new NameContainsKeywordsPredicate(secondPredicateKeywordList);
+ NameContainsKeywordsPredicate firstPredicate = new NameContainsKeywordsPredicate(firstPredicateKeyword);
+ NameContainsKeywordsPredicate secondPredicate = new NameContainsKeywordsPredicate(secondPredicateKeyword);
// same object -> returns true
assertTrue(firstPredicate.equals(firstPredicate));
// same values -> returns true
- NameContainsKeywordsPredicate firstPredicateCopy = new NameContainsKeywordsPredicate(firstPredicateKeywordList);
+ NameContainsKeywordsPredicate firstPredicateCopy = new NameContainsKeywordsPredicate(firstPredicateKeyword);
assertTrue(firstPredicate.equals(firstPredicateCopy));
// different types -> returns false
@@ -42,44 +43,54 @@ public void equals() {
@Test
public void test_nameContainsKeywords_returnsTrue() {
// One keyword
- NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Collections.singletonList("Alice"));
+ NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate("Alice");
assertTrue(predicate.test(new PersonBuilder().withName("Alice Bob").build()));
// Multiple keywords
- predicate = new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob"));
+ predicate = new NameContainsKeywordsPredicate("Alice Bob");
assertTrue(predicate.test(new PersonBuilder().withName("Alice Bob").build()));
- // Only one matching keyword
- predicate = new NameContainsKeywordsPredicate(Arrays.asList("Bob", "Carol"));
- assertTrue(predicate.test(new PersonBuilder().withName("Alice Carol").build()));
-
// Mixed-case keywords
- predicate = new NameContainsKeywordsPredicate(Arrays.asList("aLIce", "bOB"));
+ predicate = new NameContainsKeywordsPredicate("aLIce bOB");
assertTrue(predicate.test(new PersonBuilder().withName("Alice Bob").build()));
}
@Test
- public void test_nameDoesNotContainKeywords_returnsFalse() {
- // Zero keywords
- NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Collections.emptyList());
- assertFalse(predicate.test(new PersonBuilder().withName("Alice").build()));
+ public void test_keywordIsEmpty_throwsException() {
+ try {
+ NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate("");
+ assertFalse(predicate.test(new PersonBuilder().withName("Alice").build()));
+ } catch (Exception e) {
+ assertEquals("Word parameter cannot be empty", e.getMessage());
+ }
+ }
+ @Test
+ public void test_nameDoesNotContainKeywords_returnsFalse() {
// Non-matching keyword
- predicate = new NameContainsKeywordsPredicate(Arrays.asList("Carol"));
+ NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate("Carol");
assertFalse(predicate.test(new PersonBuilder().withName("Alice Bob").build()));
// Keywords match phone, email and address, but does not match name
- predicate = new NameContainsKeywordsPredicate(Arrays.asList("12345", "alice@email.com", "Main", "Street"));
- assertFalse(predicate.test(new PersonBuilder().withName("Alice").withPhone("12345")
+ predicate = new NameContainsKeywordsPredicate("91234567 alice@email.com Main Street");
+ assertFalse(predicate.test(new PersonBuilder().withName("Alice").withPhone("91234567")
.withEmail("alice@email.com").withAddress("Main Street").build()));
}
@Test
public void toStringMethod() {
- List keywords = List.of("keyword1", "keyword2");
+ String keywords = "keyword1 keyword2";
NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(keywords);
String expected = NameContainsKeywordsPredicate.class.getCanonicalName() + "{keywords=" + keywords + "}";
assertEquals(expected, predicate.toString());
}
+
+ @Test
+ public void getSuccessString() {
+ String keyword = "keyword 1";
+ NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(keyword);
+ String expected = String.format(Messages.MESSAGE_FILTER_OVERVIEW_NAME, keyword);
+ assertEquals(expected, predicate.getSuccessString());
+ }
}
diff --git a/src/test/java/seedu/address/model/person/NameTest.java b/src/test/java/hirehive/address/model/person/NameTest.java
similarity index 56%
rename from src/test/java/seedu/address/model/person/NameTest.java
rename to src/test/java/hirehive/address/model/person/NameTest.java
index 94e3dd726bd..2c2baa0e113 100644
--- a/src/test/java/seedu/address/model/person/NameTest.java
+++ b/src/test/java/hirehive/address/model/person/NameTest.java
@@ -1,41 +1,52 @@
-package seedu.address.model.person;
+package hirehive.address.model.person;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
import org.junit.jupiter.api.Test;
+import hirehive.address.testutil.Assert;
+
public class NameTest {
@Test
public void constructor_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> new Name(null));
+ Assert.assertThrows(NullPointerException.class, () -> new Name(null));
}
@Test
public void constructor_invalidName_throwsIllegalArgumentException() {
String invalidName = "";
- assertThrows(IllegalArgumentException.class, () -> new Name(invalidName));
+ Assert.assertThrows(IllegalArgumentException.class, () -> new Name(invalidName));
}
@Test
public void isValidName() {
// null name
- assertThrows(NullPointerException.class, () -> Name.isValidName(null));
+ Assert.assertThrows(NullPointerException.class, () -> Name.isValidName(null));
// invalid name
assertFalse(Name.isValidName("")); // empty string
assertFalse(Name.isValidName(" ")); // spaces only
assertFalse(Name.isValidName("^")); // only non-alphanumeric characters
assertFalse(Name.isValidName("peter*")); // contains non-alphanumeric characters
+ assertFalse(Name.isValidName("peter the 2nd")); // alphanumeric characters
+ assertFalse(Name.isValidName("12345")); // numbers only
+ assertFalse(Name.isValidName("/rachel.")); // Symbol at the start
// valid name
assertTrue(Name.isValidName("peter jack")); // alphabets only
- assertTrue(Name.isValidName("12345")); // numbers only
- assertTrue(Name.isValidName("peter the 2nd")); // alphanumeric characters
assertTrue(Name.isValidName("Capital Tan")); // with capital letters
- assertTrue(Name.isValidName("David Roger Jackson Ray Jr 2nd")); // long names
+ assertTrue(Name.isValidName("David Roger Jackson Ray Jr Second")); // long names
+ assertTrue(Name.isValidName("Rachel O'Connor")); //apostrophe
+ assertTrue(Name.isValidName("R@chel")); // commercial at
+ assertTrue(Name.isValidName("Rachel s/o Connor")); // slash
+ assertTrue(Name.isValidName("Rachel (XinYing)")); // brackets
+ assertTrue(Name.isValidName("Lee, Rachel")); // comma
+ assertTrue(Name.isValidName("Rachel-Natalie")); // hyphen
+ assertTrue(Name.isValidName("Lee. Rachel.")); // full stop
+ assertTrue(Name.isValidName("R@c/hel, Wa()l-ker."));
}
@Test
diff --git a/src/test/java/hirehive/address/model/person/NoteTest.java b/src/test/java/hirehive/address/model/person/NoteTest.java
new file mode 100644
index 00000000000..adaca731a60
--- /dev/null
+++ b/src/test/java/hirehive/address/model/person/NoteTest.java
@@ -0,0 +1,72 @@
+package hirehive.address.model.person;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.testutil.Assert;
+
+public class NoteTest {
+
+ private final String invalidNote = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo"
+ + " ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes,"
+ + " nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla"
+ + " consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim"
+ + " justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium."
+ + " Integer tincidunt. Cras dapibus";
+
+ @Test
+ public void constructor_null_throwsNullPointerException() {
+ Assert.assertThrows(NullPointerException.class, () -> new Note(null));
+ }
+
+ @Test
+ public void constructor_invalidNote_throwsIllegalArgumentException() {
+ Assert.assertThrows(IllegalArgumentException.class, () -> new Note(invalidNote));
+ }
+
+ @Test
+ public void isValidNote() {
+ // null note
+ Assert.assertThrows(NullPointerException.class, () -> Note.isValidNote(null));
+
+ // invalid note
+ assertFalse(Note.isValidNote(invalidNote)); // >500 characters
+
+ // valid note
+ assertTrue(Note.isValidNote("Very smart")); // alphabets only
+ assertTrue(Note.isValidNote("!@#$%^&*()_+")); // mix of symbols
+ }
+
+ @Test
+ public void isEmpty() {
+ // empty note, return true
+ Note empty = new Note("");
+ assertTrue(empty.isEmpty());
+
+ // non empty note, return false
+ Note nonempty = new Note("nonempty");
+ assertFalse(nonempty.isEmpty());
+ }
+
+ @Test
+ public void equals() {
+ Note note = new Note("Valid");
+
+ // same values -> returns true
+ assertTrue(note.equals(new Note("Valid")));
+
+ // same object -> returns true
+ assertTrue(note.equals(note));
+
+ // null -> returns false
+ assertFalse(note.equals(null));
+
+ // different types -> returns false
+ assertFalse(note.equals(5.0f));
+
+ // different values -> returns false
+ assertFalse(note.equals(new Note("Also valid")));
+ }
+}
diff --git a/src/test/java/hirehive/address/model/person/PersonContainsTagPredicateTest.java b/src/test/java/hirehive/address/model/person/PersonContainsTagPredicateTest.java
new file mode 100644
index 00000000000..f4ac80a3d1f
--- /dev/null
+++ b/src/test/java/hirehive/address/model/person/PersonContainsTagPredicateTest.java
@@ -0,0 +1,83 @@
+package hirehive.address.model.person;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.logic.parser.ParserUtil;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.tag.Tag;
+import hirehive.address.testutil.PersonBuilder;
+
+public class PersonContainsTagPredicateTest {
+ @Test
+ public void equals() {
+ Tag firstPredicateTag = Tag.APPLICANT;
+ Tag secondPredicateTag = Tag.CANDIDATE;
+
+ PersonContainsTagPredicate firstPredicate = new PersonContainsTagPredicate(firstPredicateTag);
+ PersonContainsTagPredicate secondPredicate = new PersonContainsTagPredicate(secondPredicateTag);
+
+ // same object -> returns true
+ assertTrue(firstPredicate.equals(firstPredicate));
+
+ // same values -> returns true
+ PersonContainsTagPredicate firstPredicateCopy = new PersonContainsTagPredicate(firstPredicateTag);
+ assertTrue(firstPredicate.equals(firstPredicateCopy));
+
+ // different types -> returns false
+ assertFalse(firstPredicate.equals(1));
+
+ // null -> returns false
+ assertFalse(firstPredicate.equals(null));
+
+ // different person -> returns false
+ assertFalse(firstPredicate.equals(secondPredicate));
+ }
+
+ @Test
+ public void test_tagContainsKeywords_returnsTrue() throws ParseException {
+ // One Tag
+ PersonContainsTagPredicate predicate = new PersonContainsTagPredicate(ParserUtil.parseTag("applicant"));
+ assertTrue(predicate.test(new PersonBuilder().withName("Alice Bob").withTag("applicant").build()));
+
+ // Mixed-case tag
+ predicate = new PersonContainsTagPredicate(ParserUtil.parseTag("Applicant"));
+ assertTrue(predicate.test(new PersonBuilder().withName("Alice Bob").withTag("applicant").build()));
+ }
+
+ @Test
+ public void test_tagDoesNotContainKeywords_returnsFalse() throws ParseException {
+ PersonContainsTagPredicate predicate = new PersonContainsTagPredicate(ParserUtil.parseTag("applicant"));
+ assertFalse(predicate.test(new PersonBuilder().withName("Alice Bob").withTag("rejected").build()));
+
+ // Keywords match phone, email and address, but does not match name
+ predicate = new PersonContainsTagPredicate(ParserUtil.parseTag("applicant"));
+ assertFalse(predicate.test(new PersonBuilder().withName("Alice").withPhone("91234567")
+ .withEmail("alice@email.com").withAddress("Main Street").withTag("rejected").build()));
+ }
+
+ @Test
+ public void toStringMethod() {
+ Tag tag = Tag.APPLICANT;
+ PersonContainsTagPredicate predicate = new PersonContainsTagPredicate(tag);
+
+ String expected = PersonContainsTagPredicate.class.getCanonicalName() + "{tag=" + tag + "}";
+ assertEquals(expected, predicate.toString());
+ }
+
+ @Test
+ public void getSuccessString() {
+ String tag = "APPLICANT";
+ PersonContainsTagPredicate predicate = new PersonContainsTagPredicate(Tag.APPLICANT);
+ String expected = String.format(Messages.MESSAGE_FILTER_OVERVIEW_TAG, tag);
+ assertEquals(expected, predicate.getSuccessString());
+ }
+}
diff --git a/src/test/java/hirehive/address/model/person/PersonTest.java b/src/test/java/hirehive/address/model/person/PersonTest.java
new file mode 100644
index 00000000000..75d0acf9d6b
--- /dev/null
+++ b/src/test/java/hirehive/address/model/person/PersonTest.java
@@ -0,0 +1,118 @@
+package hirehive.address.model.person;
+
+import static hirehive.address.logic.commands.CommandTestUtil.DEFAULT_TAG_APPLICANT;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_ADDRESS_AMY;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_DATE_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_NOTE_AMY;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_NOTE_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_ROLE_AMY;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_ROLE_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_TAG_CANDIDATE;
+import static hirehive.address.testutil.Assert.assertThrows;
+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 org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.testutil.Assert;
+import hirehive.address.testutil.PersonBuilder;
+import hirehive.address.testutil.TypicalPersons;
+
+public class PersonTest {
+ @Test
+ public void isSamePerson() {
+ // same object -> returns true
+ Assertions.assertTrue(TypicalPersons.ALICE.isSamePerson(TypicalPersons.ALICE));
+
+ // null -> returns false
+ Assertions.assertFalse(TypicalPersons.ALICE.isSamePerson(null));
+
+ // same name, all other attributes different -> returns true
+ Person editedAlice = new PersonBuilder(TypicalPersons.ALICE).withPhone(VALID_PHONE_BOB)
+ .withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB).withRole(VALID_ROLE_BOB)
+ .withTag(VALID_TAG_CANDIDATE).withNote(VALID_NOTE_BOB).withDate(VALID_DATE_BOB).build();
+ Assertions.assertTrue(TypicalPersons.ALICE.isSamePerson(editedAlice));
+
+ // different name, all other attributes same -> returns false
+ editedAlice = new PersonBuilder(TypicalPersons.ALICE).withName(VALID_NAME_BOB).build();
+ Assertions.assertFalse(TypicalPersons.ALICE.isSamePerson(editedAlice));
+
+ // name differs in case, all other attributes same -> returns true
+ Person editedBob = new PersonBuilder(TypicalPersons.BOB).withName(VALID_NAME_BOB.toLowerCase()).build();
+ Assertions.assertTrue(TypicalPersons.BOB.isSamePerson(editedBob));
+
+ // name has trailing spaces, all other attributes same -> returns true
+ String nameWithTrailingSpaces = VALID_NAME_BOB + " ";
+ editedBob = new PersonBuilder(TypicalPersons.BOB).withName(nameWithTrailingSpaces).build();
+ Assertions.assertTrue(TypicalPersons.BOB.isSamePerson(editedBob));
+
+ //name same, only phone different, all other attributes same -> returns true
+ Person editedAmy = new PersonBuilder(TypicalPersons.AMY).withPhone(VALID_PHONE_BOB)
+ .withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY).withRole(VALID_ROLE_AMY)
+ .withTag(DEFAULT_TAG_APPLICANT).withNote(VALID_NOTE_AMY).build();
+ Assertions.assertTrue(TypicalPersons.AMY.isSamePerson(editedAmy));
+ }
+
+ @Test
+ public void equals() {
+ // same values -> returns true
+ Person aliceCopy = new PersonBuilder(TypicalPersons.ALICE).build();
+ Assertions.assertTrue(TypicalPersons.ALICE.equals(aliceCopy));
+
+ // same object -> returns true
+ Assertions.assertTrue(TypicalPersons.ALICE.equals(TypicalPersons.ALICE));
+
+ // null -> returns false
+ Assertions.assertFalse(TypicalPersons.ALICE.equals(null));
+
+ // different type -> returns false
+ Assertions.assertFalse(TypicalPersons.ALICE.equals(5));
+
+ // different person -> returns false
+ Assertions.assertFalse(TypicalPersons.ALICE.equals(TypicalPersons.BOB));
+
+ // different name -> returns false
+ Person editedAlice = new PersonBuilder(TypicalPersons.ALICE).withName(VALID_NAME_BOB).build();
+ Assertions.assertFalse(TypicalPersons.ALICE.equals(editedAlice));
+
+ // different phone -> returns false
+ editedAlice = new PersonBuilder(TypicalPersons.ALICE).withPhone(VALID_PHONE_BOB).build();
+ Assertions.assertFalse(TypicalPersons.ALICE.equals(editedAlice));
+
+ // different email -> returns false
+ editedAlice = new PersonBuilder(TypicalPersons.ALICE).withEmail(VALID_EMAIL_BOB).build();
+ Assertions.assertFalse(TypicalPersons.ALICE.equals(editedAlice));
+
+ // different address -> returns false
+ editedAlice = new PersonBuilder(TypicalPersons.ALICE).withAddress(VALID_ADDRESS_BOB).build();
+ Assertions.assertFalse(TypicalPersons.ALICE.equals(editedAlice));
+
+ // different Tag -> returns false
+ editedAlice = new PersonBuilder(TypicalPersons.ALICE).withTag(VALID_TAG_CANDIDATE).build();
+ Assertions.assertFalse(TypicalPersons.ALICE.equals(editedAlice));
+
+ // different note -> returns false
+ editedAlice = new PersonBuilder(TypicalPersons.ALICE).withNote(VALID_NOTE_BOB).build();
+ Assertions.assertFalse(TypicalPersons.ALICE.equals(editedAlice));
+
+ // different date -> returns false
+ editedAlice = new PersonBuilder(TypicalPersons.ALICE).withDate(VALID_DATE_BOB).build();
+ Assertions.assertFalse(TypicalPersons.ALICE.equals(editedAlice));
+ }
+
+ @Test
+ public void toStringMethod() {
+ String expected = Person.class.getCanonicalName() + "{name=" + TypicalPersons.ALICE.getName() + ", phone=" + TypicalPersons.ALICE.getPhone()
+ + ", email=" + TypicalPersons.ALICE.getEmail() + ", address=" + TypicalPersons.ALICE.getAddress() + ", role=" + TypicalPersons.ALICE.getRole()
+ + ", tag=" + TypicalPersons.ALICE.getTag() + ", note=" + TypicalPersons.ALICE.getNote() + ", "
+ + "interviewDate=" + TypicalPersons.ALICE.getDate() + "}";
+ Assertions.assertEquals(expected, TypicalPersons.ALICE.toString());
+ }
+}
diff --git a/src/test/java/seedu/address/model/person/PhoneTest.java b/src/test/java/hirehive/address/model/person/PhoneTest.java
similarity index 60%
rename from src/test/java/seedu/address/model/person/PhoneTest.java
rename to src/test/java/hirehive/address/model/person/PhoneTest.java
index deaaa5ba190..35b1a8e915d 100644
--- a/src/test/java/seedu/address/model/person/PhoneTest.java
+++ b/src/test/java/hirehive/address/model/person/PhoneTest.java
@@ -1,49 +1,51 @@
-package seedu.address.model.person;
+package hirehive.address.model.person;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
import org.junit.jupiter.api.Test;
+import hirehive.address.testutil.Assert;
+
public class PhoneTest {
@Test
public void constructor_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> new Phone(null));
+ Assert.assertThrows(NullPointerException.class, () -> new Phone(null));
}
@Test
public void constructor_invalidPhone_throwsIllegalArgumentException() {
String invalidPhone = "";
- assertThrows(IllegalArgumentException.class, () -> new Phone(invalidPhone));
+ Assert.assertThrows(IllegalArgumentException.class, () -> new Phone(invalidPhone));
}
@Test
public void isValidPhone() {
// null phone number
- assertThrows(NullPointerException.class, () -> Phone.isValidPhone(null));
+ Assert.assertThrows(NullPointerException.class, () -> Phone.isValidPhone(null));
// invalid phone numbers
assertFalse(Phone.isValidPhone("")); // empty string
assertFalse(Phone.isValidPhone(" ")); // spaces only
- assertFalse(Phone.isValidPhone("91")); // less than 3 numbers
+ assertFalse(Phone.isValidPhone("911384")); // less than 8 numbers
assertFalse(Phone.isValidPhone("phone")); // non-numeric
assertFalse(Phone.isValidPhone("9011p041")); // alphabets within digits
assertFalse(Phone.isValidPhone("9312 1534")); // spaces within digits
// valid phone numbers
- assertTrue(Phone.isValidPhone("911")); // exactly 3 numbers
- assertTrue(Phone.isValidPhone("93121534"));
- assertTrue(Phone.isValidPhone("124293842033123")); // long phone numbers
+ assertTrue(Phone.isValidPhone("91112345")); // exactly 8 numbers
+ assertTrue(Phone.isValidPhone("81234567"));
+ assertTrue(Phone.isValidPhone("61234567"));
}
@Test
public void equals() {
- Phone phone = new Phone("999");
+ Phone phone = new Phone("98765432");
// same values -> returns true
- assertTrue(phone.equals(new Phone("999")));
+ assertTrue(phone.equals(new Phone("98765432")));
// same object -> returns true
assertTrue(phone.equals(phone));
@@ -55,6 +57,6 @@ public void equals() {
assertFalse(phone.equals(5.0f));
// different values -> returns false
- assertFalse(phone.equals(new Phone("995")));
+ assertFalse(phone.equals(new Phone("87654321")));
}
}
diff --git a/src/test/java/seedu/address/model/person/UniquePersonListTest.java b/src/test/java/hirehive/address/model/person/UniquePersonListTest.java
similarity index 50%
rename from src/test/java/seedu/address/model/person/UniquePersonListTest.java
rename to src/test/java/hirehive/address/model/person/UniquePersonListTest.java
index 17ae501df08..78bca7118f7 100644
--- a/src/test/java/seedu/address/model/person/UniquePersonListTest.java
+++ b/src/test/java/hirehive/address/model/person/UniquePersonListTest.java
@@ -1,13 +1,11 @@
-package seedu.address.model.person;
+package hirehive.address.model.person;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_TAG_CANDIDATE;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.BOB;
import java.util.Arrays;
import java.util.Collections;
@@ -15,9 +13,11 @@
import org.junit.jupiter.api.Test;
-import seedu.address.model.person.exceptions.DuplicatePersonException;
-import seedu.address.model.person.exceptions.PersonNotFoundException;
-import seedu.address.testutil.PersonBuilder;
+import hirehive.address.model.person.exceptions.DuplicatePersonException;
+import hirehive.address.model.person.exceptions.PersonNotFoundException;
+import hirehive.address.testutil.Assert;
+import hirehive.address.testutil.PersonBuilder;
+import hirehive.address.testutil.TypicalPersons;
public class UniquePersonListTest {
@@ -25,69 +25,69 @@ public class UniquePersonListTest {
@Test
public void contains_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.contains(null));
+ Assert.assertThrows(NullPointerException.class, () -> uniquePersonList.contains(null));
}
@Test
public void contains_personNotInList_returnsFalse() {
- assertFalse(uniquePersonList.contains(ALICE));
+ assertFalse(uniquePersonList.contains(TypicalPersons.ALICE));
}
@Test
public void contains_personInList_returnsTrue() {
- uniquePersonList.add(ALICE);
- assertTrue(uniquePersonList.contains(ALICE));
+ uniquePersonList.add(TypicalPersons.ALICE);
+ assertTrue(uniquePersonList.contains(TypicalPersons.ALICE));
}
@Test
public void contains_personWithSameIdentityFieldsInList_returnsTrue() {
- uniquePersonList.add(ALICE);
- Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND)
+ uniquePersonList.add(TypicalPersons.ALICE);
+ Person editedAlice = new PersonBuilder(TypicalPersons.ALICE).withAddress(VALID_ADDRESS_BOB).withTag(VALID_TAG_CANDIDATE)
.build();
assertTrue(uniquePersonList.contains(editedAlice));
}
@Test
public void add_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.add(null));
+ Assert.assertThrows(NullPointerException.class, () -> uniquePersonList.add(null));
}
@Test
public void add_duplicatePerson_throwsDuplicatePersonException() {
- uniquePersonList.add(ALICE);
- assertThrows(DuplicatePersonException.class, () -> uniquePersonList.add(ALICE));
+ uniquePersonList.add(TypicalPersons.ALICE);
+ Assert.assertThrows(DuplicatePersonException.class, () -> uniquePersonList.add(TypicalPersons.ALICE));
}
@Test
public void setPerson_nullTargetPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.setPerson(null, ALICE));
+ Assert.assertThrows(NullPointerException.class, () -> uniquePersonList.setPerson(null, TypicalPersons.ALICE));
}
@Test
public void setPerson_nullEditedPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.setPerson(ALICE, null));
+ Assert.assertThrows(NullPointerException.class, () -> uniquePersonList.setPerson(TypicalPersons.ALICE, null));
}
@Test
public void setPerson_targetPersonNotInList_throwsPersonNotFoundException() {
- assertThrows(PersonNotFoundException.class, () -> uniquePersonList.setPerson(ALICE, ALICE));
+ Assert.assertThrows(PersonNotFoundException.class, () -> uniquePersonList.setPerson(TypicalPersons.ALICE, TypicalPersons.ALICE));
}
@Test
public void setPerson_editedPersonIsSamePerson_success() {
- uniquePersonList.add(ALICE);
- uniquePersonList.setPerson(ALICE, ALICE);
+ uniquePersonList.add(TypicalPersons.ALICE);
+ uniquePersonList.setPerson(TypicalPersons.ALICE, TypicalPersons.ALICE);
UniquePersonList expectedUniquePersonList = new UniquePersonList();
- expectedUniquePersonList.add(ALICE);
+ expectedUniquePersonList.add(TypicalPersons.ALICE);
assertEquals(expectedUniquePersonList, uniquePersonList);
}
@Test
public void setPerson_editedPersonHasSameIdentity_success() {
- uniquePersonList.add(ALICE);
- Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND)
+ uniquePersonList.add(TypicalPersons.ALICE);
+ Person editedAlice = new PersonBuilder(TypicalPersons.ALICE).withAddress(VALID_ADDRESS_BOB).withTag(VALID_TAG_CANDIDATE)
.build();
- uniquePersonList.setPerson(ALICE, editedAlice);
+ uniquePersonList.setPerson(TypicalPersons.ALICE, editedAlice);
UniquePersonList expectedUniquePersonList = new UniquePersonList();
expectedUniquePersonList.add(editedAlice);
assertEquals(expectedUniquePersonList, uniquePersonList);
@@ -95,76 +95,76 @@ public void setPerson_editedPersonHasSameIdentity_success() {
@Test
public void setPerson_editedPersonHasDifferentIdentity_success() {
- uniquePersonList.add(ALICE);
- uniquePersonList.setPerson(ALICE, BOB);
+ uniquePersonList.add(TypicalPersons.ALICE);
+ uniquePersonList.setPerson(TypicalPersons.ALICE, TypicalPersons.BOB);
UniquePersonList expectedUniquePersonList = new UniquePersonList();
- expectedUniquePersonList.add(BOB);
+ expectedUniquePersonList.add(TypicalPersons.BOB);
assertEquals(expectedUniquePersonList, uniquePersonList);
}
@Test
public void setPerson_editedPersonHasNonUniqueIdentity_throwsDuplicatePersonException() {
- uniquePersonList.add(ALICE);
- uniquePersonList.add(BOB);
- assertThrows(DuplicatePersonException.class, () -> uniquePersonList.setPerson(ALICE, BOB));
+ uniquePersonList.add(TypicalPersons.ALICE);
+ uniquePersonList.add(TypicalPersons.BOB);
+ Assert.assertThrows(DuplicatePersonException.class, () -> uniquePersonList.setPerson(TypicalPersons.ALICE, TypicalPersons.BOB));
}
@Test
public void remove_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.remove(null));
+ Assert.assertThrows(NullPointerException.class, () -> uniquePersonList.remove(null));
}
@Test
public void remove_personDoesNotExist_throwsPersonNotFoundException() {
- assertThrows(PersonNotFoundException.class, () -> uniquePersonList.remove(ALICE));
+ Assert.assertThrows(PersonNotFoundException.class, () -> uniquePersonList.remove(TypicalPersons.ALICE));
}
@Test
public void remove_existingPerson_removesPerson() {
- uniquePersonList.add(ALICE);
- uniquePersonList.remove(ALICE);
+ uniquePersonList.add(TypicalPersons.ALICE);
+ uniquePersonList.remove(TypicalPersons.ALICE);
UniquePersonList expectedUniquePersonList = new UniquePersonList();
assertEquals(expectedUniquePersonList, uniquePersonList);
}
@Test
public void setPersons_nullUniquePersonList_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.setPersons((UniquePersonList) null));
+ Assert.assertThrows(NullPointerException.class, () -> uniquePersonList.setPersons((UniquePersonList) null));
}
@Test
public void setPersons_uniquePersonList_replacesOwnListWithProvidedUniquePersonList() {
- uniquePersonList.add(ALICE);
+ uniquePersonList.add(TypicalPersons.ALICE);
UniquePersonList expectedUniquePersonList = new UniquePersonList();
- expectedUniquePersonList.add(BOB);
+ expectedUniquePersonList.add(TypicalPersons.BOB);
uniquePersonList.setPersons(expectedUniquePersonList);
assertEquals(expectedUniquePersonList, uniquePersonList);
}
@Test
public void setPersons_nullList_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.setPersons((List) null));
+ Assert.assertThrows(NullPointerException.class, () -> uniquePersonList.setPersons((List) null));
}
@Test
public void setPersons_list_replacesOwnListWithProvidedList() {
- uniquePersonList.add(ALICE);
- List personList = Collections.singletonList(BOB);
+ uniquePersonList.add(TypicalPersons.ALICE);
+ List personList = Collections.singletonList(TypicalPersons.BOB);
uniquePersonList.setPersons(personList);
UniquePersonList expectedUniquePersonList = new UniquePersonList();
- expectedUniquePersonList.add(BOB);
+ expectedUniquePersonList.add(TypicalPersons.BOB);
assertEquals(expectedUniquePersonList, uniquePersonList);
}
@Test
public void setPersons_listWithDuplicatePersons_throwsDuplicatePersonException() {
- List listWithDuplicatePersons = Arrays.asList(ALICE, ALICE);
- assertThrows(DuplicatePersonException.class, () -> uniquePersonList.setPersons(listWithDuplicatePersons));
+ List listWithDuplicatePersons = Arrays.asList(TypicalPersons.ALICE, TypicalPersons.ALICE);
+ Assert.assertThrows(DuplicatePersonException.class, () -> uniquePersonList.setPersons(listWithDuplicatePersons));
}
@Test
public void asUnmodifiableObservableList_modifyList_throwsUnsupportedOperationException() {
- assertThrows(UnsupportedOperationException.class, ()
+ Assert.assertThrows(UnsupportedOperationException.class, ()
-> uniquePersonList.asUnmodifiableObservableList().remove(0));
}
diff --git a/src/test/java/hirehive/address/model/person/UpcomingInterviewPredicateTest.java b/src/test/java/hirehive/address/model/person/UpcomingInterviewPredicateTest.java
new file mode 100644
index 00000000000..357a2c68079
--- /dev/null
+++ b/src/test/java/hirehive/address/model/person/UpcomingInterviewPredicateTest.java
@@ -0,0 +1,85 @@
+package hirehive.address.model.person;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.logic.Messages;
+import hirehive.address.testutil.PersonBuilder;
+
+public class UpcomingInterviewPredicateTest {
+ public static final String TEST_CURRENT_DAY = "01/01/2025";
+
+ @Test
+ public void equals() {
+ int firstPredicateDays = 5;
+ int secondPredicateDays = 10;
+
+ UpcomingInterviewPredicate firstPredicate = new UpcomingInterviewPredicate(firstPredicateDays, TEST_CURRENT_DAY);
+ UpcomingInterviewPredicate secondPredicate = new UpcomingInterviewPredicate(secondPredicateDays, TEST_CURRENT_DAY);
+
+ // same object -> returns true
+ assertTrue(firstPredicate.equals(firstPredicate));
+
+ // same values -> returns true
+ UpcomingInterviewPredicate firstPredicateCopy = new UpcomingInterviewPredicate(firstPredicateDays, TEST_CURRENT_DAY);
+ assertTrue(firstPredicate.equals(firstPredicateCopy));
+
+ // different types -> returns false
+ assertFalse(firstPredicate.equals(1));
+
+ // null -> returns false
+ assertFalse(firstPredicate.equals(null));
+
+ // different person -> returns false
+ assertFalse(firstPredicate.equals(secondPredicate));
+ }
+
+ @Test
+ public void test_dateWithinDays_returnsTrue() {
+ // Within range
+ UpcomingInterviewPredicate predicate = new UpcomingInterviewPredicate(5, TEST_CURRENT_DAY);
+ assertTrue(predicate.test(new PersonBuilder().withDate("03/01/2025").build()));
+
+ // Boundary date
+ predicate = new UpcomingInterviewPredicate(5, TEST_CURRENT_DAY);
+ assertTrue(predicate.test(new PersonBuilder().withDate("06/01/2025").build()));
+
+ // Same date
+ predicate = new UpcomingInterviewPredicate(5, TEST_CURRENT_DAY);
+ assertTrue(predicate.test(new PersonBuilder().withDate(TEST_CURRENT_DAY).build()));
+ }
+
+ @Test
+ public void test_dateNotWithinDays_returnsTrue() {
+ // Within range
+ UpcomingInterviewPredicate predicate = new UpcomingInterviewPredicate(5, TEST_CURRENT_DAY);
+ assertFalse(predicate.test(new PersonBuilder().withDate("15/01/2025").build()));
+
+ // Boundary date
+ predicate = new UpcomingInterviewPredicate(5, TEST_CURRENT_DAY);
+ assertFalse(predicate.test(new PersonBuilder().withDate("07/01/2025").build()));
+
+ // Date is within range before the current date
+ predicate = new UpcomingInterviewPredicate(5, TEST_CURRENT_DAY);
+ assertFalse(predicate.test(new PersonBuilder().withDate("31/12/2024").build()));
+
+ // No interview date
+ predicate = new UpcomingInterviewPredicate(5, TEST_CURRENT_DAY);
+ assertFalse(predicate.test(new PersonBuilder().build()));
+
+ // Date is before the current date
+ predicate = new UpcomingInterviewPredicate(5, TEST_CURRENT_DAY);
+ assertFalse(predicate.test(new PersonBuilder().withDate("01/01/2024").build()));
+ }
+
+ @Test
+ public void getSuccessString() {
+ int days = 5;
+ UpcomingInterviewPredicate predicate = new UpcomingInterviewPredicate(5);
+ String expected = String.format(Messages.MESSAGE_FILTER_OVERVIEW_DATE, days);
+ assertEquals(expected, predicate.getSuccessString());
+ }
+}
diff --git a/src/test/java/hirehive/address/model/tag/TagTest.java b/src/test/java/hirehive/address/model/tag/TagTest.java
new file mode 100644
index 00000000000..762b7f0244c
--- /dev/null
+++ b/src/test/java/hirehive/address/model/tag/TagTest.java
@@ -0,0 +1,21 @@
+package hirehive.address.model.tag;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.testutil.Assert;
+
+public class TagTest {
+
+ @Test
+ public void test_getDefaultTag_returnsTrue() {
+ assertEquals(Tag.getDefaultTag(), Tag.APPLICANT);
+ }
+
+ @Test
+ public void test_getDefaultTag_returnsFalse() {
+ assertFalse(Tag.getDefaultTag().equals(Tag.CANDIDATE));
+ }
+}
diff --git a/src/test/java/hirehive/address/model/util/SampleDataUtilTest.java b/src/test/java/hirehive/address/model/util/SampleDataUtilTest.java
new file mode 100644
index 00000000000..bf980d416a9
--- /dev/null
+++ b/src/test/java/hirehive/address/model/util/SampleDataUtilTest.java
@@ -0,0 +1,23 @@
+package hirehive.address.model.util;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.model.ReadOnlyAddressBook;
+import hirehive.address.model.person.Person;
+
+public class SampleDataUtilTest {
+
+ private final Person[] samplePersons = SampleDataUtil.getSamplePersons();
+ private final ReadOnlyAddressBook sampleAddressBook = SampleDataUtil.getSampleAddressBook();
+
+ @Test
+ public void getSampleAddressBook_containsAllSamplePersons() {
+ for (Person person : samplePersons) {
+ assertTrue(sampleAddressBook.getPersonList().contains(person),
+ "AddressBook should contain: " + person);
+ }
+ }
+
+}
diff --git a/src/test/java/hirehive/address/storage/JsonAdaptedPersonTest.java b/src/test/java/hirehive/address/storage/JsonAdaptedPersonTest.java
new file mode 100644
index 00000000000..d4f6a0a1350
--- /dev/null
+++ b/src/test/java/hirehive/address/storage/JsonAdaptedPersonTest.java
@@ -0,0 +1,178 @@
+package hirehive.address.storage;
+
+import static hirehive.address.testutil.Assert.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import hirehive.address.commons.exceptions.IllegalValueException;
+import hirehive.address.model.person.Address;
+import hirehive.address.model.person.Email;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.Name;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Phone;
+import hirehive.address.model.person.Role;
+import hirehive.address.testutil.Assert;
+import hirehive.address.testutil.TypicalPersons;
+
+public class JsonAdaptedPersonTest {
+ private static final String INVALID_NAME = "R4chel";
+ private static final String INVALID_PHONE = "+651234";
+ private static final String INVALID_ADDRESS = " ";
+ private static final String INVALID_EMAIL = "example.com";
+ private static final String INVALID_ROLE = "@developer";
+ private static final String INVALID_TAG = "#friend";
+ private static final String INVALID_NOTE = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean"
+ + " commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes,"
+ + " nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla"
+ + " consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim"
+ + " justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium."
+ + " Integer tincidunt. Cras dapibus";
+ private static final String INVALID_DATE = "01012004";
+ private static final String VALID_NAME = TypicalPersons.BENSON.getName().toString();
+ private static final String VALID_PHONE = TypicalPersons.BENSON.getPhone().toString();
+ private static final String VALID_EMAIL = TypicalPersons.BENSON.getEmail().toString();
+ private static final String VALID_ADDRESS = TypicalPersons.BENSON.getAddress().toString();
+ private static final String VALID_ROLE = TypicalPersons.BENSON.getRole().toString();
+ private static final String VALID_TAG = TypicalPersons.BENSON.getTag().getTagName();
+ private static final String VALID_NOTE = TypicalPersons.BENSON.getNote().toString();
+ private static final String VALID_DATE = TypicalPersons.BENSON.getDate().toString();
+
+ @Test
+ public void toModelType_validPersonDetails_returnsPerson() throws Exception {
+ JsonAdaptedPerson person = new JsonAdaptedPerson(TypicalPersons.BENSON);
+ Assertions.assertEquals(TypicalPersons.BENSON, person.toModelType());
+ }
+
+ @Test
+ public void toModelType_invalidName_throwsIllegalValueException() {
+ JsonAdaptedPerson person =
+ new JsonAdaptedPerson(INVALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_ROLE, VALID_TAG,
+ VALID_NOTE, VALID_DATE);
+ String expectedMessage = Name.MESSAGE_CONSTRAINTS;
+ Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+ }
+
+ @Test
+ public void toModelType_nullName_throwsIllegalValueException() {
+ JsonAdaptedPerson person = new JsonAdaptedPerson(
+ null, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_ROLE, VALID_TAG, VALID_NOTE, VALID_DATE);
+ String expectedMessage = String.format(JsonAdaptedPerson.MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName());
+ Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+ }
+
+ @Test
+ public void toModelType_invalidPhone_throwsIllegalValueException() {
+ JsonAdaptedPerson person =
+ new JsonAdaptedPerson(VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_ROLE, VALID_TAG,
+ VALID_NOTE, VALID_DATE);
+ String expectedMessage = Phone.MESSAGE_CONSTRAINTS;
+ Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+ }
+
+ @Test
+ public void toModelType_nullPhone_throwsIllegalValueException() {
+ JsonAdaptedPerson person = new JsonAdaptedPerson(
+ VALID_NAME, null, VALID_EMAIL, VALID_ADDRESS, VALID_ROLE, VALID_TAG, VALID_NOTE, VALID_DATE);
+ String expectedMessage = String.format(JsonAdaptedPerson.MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName());
+ Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+ }
+
+ @Test
+ public void toModelType_invalidEmail_throwsIllegalValueException() {
+ JsonAdaptedPerson person =
+ new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, INVALID_EMAIL, VALID_ADDRESS, VALID_ROLE, VALID_TAG,
+ VALID_NOTE, VALID_DATE);
+ String expectedMessage = Email.MESSAGE_CONSTRAINTS;
+ Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+ }
+
+ @Test
+ public void toModelType_nullEmail_throwsIllegalValueException() {
+ JsonAdaptedPerson person = new JsonAdaptedPerson(
+ VALID_NAME, VALID_PHONE, null, VALID_ADDRESS, VALID_ROLE, VALID_TAG, VALID_NOTE, VALID_DATE);
+ String expectedMessage = String.format(JsonAdaptedPerson.MISSING_FIELD_MESSAGE_FORMAT, Email.class.getSimpleName());
+ Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+ }
+
+ @Test
+ public void toModelType_invalidAddress_throwsIllegalValueException() {
+ JsonAdaptedPerson person =
+ new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, INVALID_ADDRESS, VALID_ROLE, VALID_TAG,
+ VALID_NOTE, VALID_DATE);
+ String expectedMessage = Address.MESSAGE_CONSTRAINTS;
+ Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+ }
+
+ @Test
+ public void toModelType_nullAddress_throwsIllegalValueException() {
+ JsonAdaptedPerson person = new JsonAdaptedPerson(
+ VALID_NAME, VALID_PHONE, VALID_EMAIL, null, VALID_ROLE, VALID_TAG, VALID_NOTE, VALID_DATE);
+ String expectedMessage = String.format(JsonAdaptedPerson.MISSING_FIELD_MESSAGE_FORMAT, Address.class.getSimpleName());
+ Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+ }
+
+ @Test
+ public void toModelType_invalidRole_throwsIllegalValueException() {
+ JsonAdaptedPerson person =
+ new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, INVALID_ROLE, VALID_TAG,
+ VALID_NOTE, VALID_DATE);
+ String expectedMessage = Role.MESSAGE_CONSTRAINTS;
+ Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+ }
+
+ @Test
+ public void toModelType_nullRole_throwsIllegalValueException() {
+ JsonAdaptedPerson person = new JsonAdaptedPerson(
+ VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, null, VALID_TAG, VALID_NOTE, VALID_DATE);
+ String expectedMessage = String.format(JsonAdaptedPerson.MISSING_FIELD_MESSAGE_FORMAT, Role.class.getSimpleName());
+ Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+ }
+
+ @Test
+ public void toModelType_invalidTags_throwsIllegalValueException() {
+ String invalidTag = "test";
+ JsonAdaptedPerson person =
+ new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_ROLE, invalidTag,
+ VALID_NOTE, VALID_DATE);
+ Assert.assertThrows(IllegalValueException.class, person::toModelType);
+ }
+
+ @Test
+ public void toModelType_invalidNote_throwsIllegalValueException() {
+ JsonAdaptedPerson person = new JsonAdaptedPerson(
+ VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_ROLE, VALID_TAG, INVALID_NOTE, VALID_DATE);
+ String expectedMessage = Note.MESSAGE_CONSTRAINTS;
+ Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+ }
+
+ @Test
+ public void toModelType_nullNote_throwsIllegalValueException() {
+ JsonAdaptedPerson person = new JsonAdaptedPerson(
+ VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_ROLE, VALID_TAG, null, VALID_DATE);
+ String expectedMessage = String.format(JsonAdaptedPerson.MISSING_FIELD_MESSAGE_FORMAT, Note.class.getSimpleName());
+ Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+ }
+
+ @Test
+ public void toModelType_invalidDate_throwsIllegalValueException() {
+ JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_ROLE, VALID_TAG,
+ VALID_NOTE, INVALID_DATE);
+ String expectedMessage = InterviewDate.MESSAGE_CONSTRAINTS;
+ Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+ }
+
+ @Test
+ public void toModelType_nullDate_throwsIllegalValueException() {
+ JsonAdaptedPerson person = new JsonAdaptedPerson(
+ VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_ROLE, VALID_TAG, VALID_NOTE, null);
+ String expectedMessage = String.format(JsonAdaptedPerson.MISSING_FIELD_MESSAGE_FORMAT, InterviewDate.class.getSimpleName());
+ Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+ }
+}
diff --git a/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java b/src/test/java/hirehive/address/storage/JsonAddressBookStorageTest.java
similarity index 72%
rename from src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java
rename to src/test/java/hirehive/address/storage/JsonAddressBookStorageTest.java
index 4e5ce9200c8..401da65525d 100644
--- a/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java
+++ b/src/test/java/hirehive/address/storage/JsonAddressBookStorageTest.java
@@ -1,12 +1,8 @@
-package seedu.address.storage;
+package hirehive.address.storage;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.HOON;
-import static seedu.address.testutil.TypicalPersons.IDA;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
import java.io.IOException;
import java.nio.file.Path;
@@ -15,9 +11,11 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.model.AddressBook;
-import seedu.address.model.ReadOnlyAddressBook;
+import hirehive.address.commons.exceptions.DataLoadingException;
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.ReadOnlyAddressBook;
+import hirehive.address.testutil.Assert;
+import hirehive.address.testutil.TypicalPersons;
public class JsonAddressBookStorageTest {
private static final Path TEST_DATA_FOLDER = Paths.get("src", "test", "data", "JsonAddressBookStorageTest");
@@ -27,7 +25,7 @@ public class JsonAddressBookStorageTest {
@Test
public void readAddressBook_nullFilePath_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> readAddressBook(null));
+ Assert.assertThrows(NullPointerException.class, () -> readAddressBook(null));
}
private java.util.Optional readAddressBook(String filePath) throws Exception {
@@ -47,23 +45,23 @@ public void read_missingFile_emptyResult() throws Exception {
@Test
public void read_notJsonFormat_exceptionThrown() {
- assertThrows(DataLoadingException.class, () -> readAddressBook("notJsonFormatAddressBook.json"));
+ Assert.assertThrows(DataLoadingException.class, () -> readAddressBook("notJsonFormatAddressBook.json"));
}
@Test
public void readAddressBook_invalidPersonAddressBook_throwDataLoadingException() {
- assertThrows(DataLoadingException.class, () -> readAddressBook("invalidPersonAddressBook.json"));
+ Assert.assertThrows(DataLoadingException.class, () -> readAddressBook("invalidPersonAddressBook.json"));
}
@Test
public void readAddressBook_invalidAndValidPersonAddressBook_throwDataLoadingException() {
- assertThrows(DataLoadingException.class, () -> readAddressBook("invalidAndValidPersonAddressBook.json"));
+ Assert.assertThrows(DataLoadingException.class, () -> readAddressBook("invalidAndValidPersonAddressBook.json"));
}
@Test
public void readAndSaveAddressBook_allInOrder_success() throws Exception {
Path filePath = testFolder.resolve("TempAddressBook.json");
- AddressBook original = getTypicalAddressBook();
+ AddressBook original = TypicalPersons.getTypicalAddressBook();
JsonAddressBookStorage jsonAddressBookStorage = new JsonAddressBookStorage(filePath);
// Save in new file and read back
@@ -72,14 +70,14 @@ public void readAndSaveAddressBook_allInOrder_success() throws Exception {
assertEquals(original, new AddressBook(readBack));
// Modify data, overwrite exiting file, and read back
- original.addPerson(HOON);
- original.removePerson(ALICE);
+ original.addPerson(TypicalPersons.HOON);
+ original.removePerson(TypicalPersons.ALICE);
jsonAddressBookStorage.saveAddressBook(original, filePath);
readBack = jsonAddressBookStorage.readAddressBook(filePath).get();
assertEquals(original, new AddressBook(readBack));
// Save and read without specifying file path
- original.addPerson(IDA);
+ original.addPerson(TypicalPersons.IDA);
jsonAddressBookStorage.saveAddressBook(original); // file path not specified
readBack = jsonAddressBookStorage.readAddressBook().get(); // file path not specified
assertEquals(original, new AddressBook(readBack));
@@ -88,7 +86,7 @@ public void readAndSaveAddressBook_allInOrder_success() throws Exception {
@Test
public void saveAddressBook_nullAddressBook_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> saveAddressBook(null, "SomeFile.json"));
+ Assert.assertThrows(NullPointerException.class, () -> saveAddressBook(null, "SomeFile.json"));
}
/**
@@ -105,6 +103,6 @@ private void saveAddressBook(ReadOnlyAddressBook addressBook, String filePath) {
@Test
public void saveAddressBook_nullFilePath_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> saveAddressBook(new AddressBook(), null));
+ Assert.assertThrows(NullPointerException.class, () -> saveAddressBook(new AddressBook(), null));
}
}
diff --git a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java b/src/test/java/hirehive/address/storage/JsonSerializableAddressBookTest.java
similarity index 76%
rename from src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java
rename to src/test/java/hirehive/address/storage/JsonSerializableAddressBookTest.java
index 188c9058d20..b17aadc272d 100644
--- a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java
+++ b/src/test/java/hirehive/address/storage/JsonSerializableAddressBookTest.java
@@ -1,17 +1,18 @@
-package seedu.address.storage;
+package hirehive.address.storage;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static seedu.address.testutil.Assert.assertThrows;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.Test;
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.commons.util.JsonUtil;
-import seedu.address.model.AddressBook;
-import seedu.address.testutil.TypicalPersons;
+import hirehive.address.commons.exceptions.IllegalValueException;
+import hirehive.address.commons.util.JsonUtil;
+import hirehive.address.model.AddressBook;
+import hirehive.address.testutil.Assert;
+import hirehive.address.testutil.TypicalPersons;
public class JsonSerializableAddressBookTest {
@@ -33,14 +34,14 @@ public void toModelType_typicalPersonsFile_success() throws Exception {
public void toModelType_invalidPersonFile_throwsIllegalValueException() throws Exception {
JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(INVALID_PERSON_FILE,
JsonSerializableAddressBook.class).get();
- assertThrows(IllegalValueException.class, dataFromFile::toModelType);
+ Assert.assertThrows(IllegalValueException.class, dataFromFile::toModelType);
}
@Test
public void toModelType_duplicatePersons_throwsIllegalValueException() throws Exception {
JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(DUPLICATE_PERSON_FILE,
JsonSerializableAddressBook.class).get();
- assertThrows(IllegalValueException.class, JsonSerializableAddressBook.MESSAGE_DUPLICATE_PERSON,
+ Assert.assertThrows(IllegalValueException.class, JsonSerializableAddressBook.MESSAGE_DUPLICATE_PERSON,
dataFromFile::toModelType);
}
diff --git a/src/test/java/seedu/address/storage/JsonUserPrefsStorageTest.java b/src/test/java/hirehive/address/storage/JsonUserPrefsStorageTest.java
similarity index 85%
rename from src/test/java/seedu/address/storage/JsonUserPrefsStorageTest.java
rename to src/test/java/hirehive/address/storage/JsonUserPrefsStorageTest.java
index ed0a413526a..b0e91f0bcdb 100644
--- a/src/test/java/seedu/address/storage/JsonUserPrefsStorageTest.java
+++ b/src/test/java/hirehive/address/storage/JsonUserPrefsStorageTest.java
@@ -1,8 +1,8 @@
-package seedu.address.storage;
+package hirehive.address.storage;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
-import static seedu.address.testutil.Assert.assertThrows;
import java.io.IOException;
import java.nio.file.Path;
@@ -12,9 +12,10 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.model.UserPrefs;
+import hirehive.address.commons.core.GuiSettings;
+import hirehive.address.commons.exceptions.DataLoadingException;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.testutil.Assert;
public class JsonUserPrefsStorageTest {
@@ -25,7 +26,7 @@ public class JsonUserPrefsStorageTest {
@Test
public void readUserPrefs_nullFilePath_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> readUserPrefs(null));
+ Assert.assertThrows(NullPointerException.class, () -> readUserPrefs(null));
}
private Optional readUserPrefs(String userPrefsFileInTestDataFolder) throws DataLoadingException {
@@ -40,7 +41,7 @@ public void readUserPrefs_missingFile_emptyResult() throws DataLoadingException
@Test
public void readUserPrefs_notJsonFormat_exceptionThrown() {
- assertThrows(DataLoadingException.class, () -> readUserPrefs("NotJsonFormatUserPrefs.json"));
+ Assert.assertThrows(DataLoadingException.class, () -> readUserPrefs("NotJsonFormatUserPrefs.json"));
}
private Path addToTestDataPathIfNotNull(String userPrefsFileInTestDataFolder) {
@@ -79,12 +80,12 @@ private UserPrefs getTypicalUserPrefs() {
@Test
public void savePrefs_nullPrefs_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> saveUserPrefs(null, "SomeFile.json"));
+ Assert.assertThrows(NullPointerException.class, () -> saveUserPrefs(null, "SomeFile.json"));
}
@Test
public void saveUserPrefs_nullFilePath_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> saveUserPrefs(new UserPrefs(), null));
+ Assert.assertThrows(NullPointerException.class, () -> saveUserPrefs(new UserPrefs(), null));
}
/**
diff --git a/src/test/java/seedu/address/storage/StorageManagerTest.java b/src/test/java/hirehive/address/storage/StorageManagerTest.java
similarity index 86%
rename from src/test/java/seedu/address/storage/StorageManagerTest.java
rename to src/test/java/hirehive/address/storage/StorageManagerTest.java
index 99a16548970..9920b528895 100644
--- a/src/test/java/seedu/address/storage/StorageManagerTest.java
+++ b/src/test/java/hirehive/address/storage/StorageManagerTest.java
@@ -1,8 +1,7 @@
-package seedu.address.storage;
+package hirehive.address.storage;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
import java.nio.file.Path;
@@ -10,10 +9,11 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.model.AddressBook;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.UserPrefs;
+import hirehive.address.commons.core.GuiSettings;
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.ReadOnlyAddressBook;
+import hirehive.address.model.UserPrefs;
+import hirehive.address.testutil.TypicalPersons;
public class StorageManagerTest {
@@ -54,7 +54,7 @@ public void addressBookReadSave() throws Exception {
* {@link JsonAddressBookStorage} class.
* More extensive testing of UserPref saving/reading is done in {@link JsonAddressBookStorageTest} class.
*/
- AddressBook original = getTypicalAddressBook();
+ AddressBook original = TypicalPersons.getTypicalAddressBook();
storageManager.saveAddressBook(original);
ReadOnlyAddressBook retrieved = storageManager.readAddressBook().get();
assertEquals(original, new AddressBook(retrieved));
diff --git a/src/test/java/seedu/address/testutil/AddressBookBuilder.java b/src/test/java/hirehive/address/testutil/AddressBookBuilder.java
similarity index 85%
rename from src/test/java/seedu/address/testutil/AddressBookBuilder.java
rename to src/test/java/hirehive/address/testutil/AddressBookBuilder.java
index d53799fd110..3ddef0dfe6d 100644
--- a/src/test/java/seedu/address/testutil/AddressBookBuilder.java
+++ b/src/test/java/hirehive/address/testutil/AddressBookBuilder.java
@@ -1,7 +1,7 @@
-package seedu.address.testutil;
+package hirehive.address.testutil;
-import seedu.address.model.AddressBook;
-import seedu.address.model.person.Person;
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.person.Person;
/**
* A utility class to help with building Addressbook objects.
diff --git a/src/test/java/seedu/address/testutil/Assert.java b/src/test/java/hirehive/address/testutil/Assert.java
similarity index 97%
rename from src/test/java/seedu/address/testutil/Assert.java
rename to src/test/java/hirehive/address/testutil/Assert.java
index 9863093bd6e..b41ddab5200 100644
--- a/src/test/java/seedu/address/testutil/Assert.java
+++ b/src/test/java/hirehive/address/testutil/Assert.java
@@ -1,4 +1,4 @@
-package seedu.address.testutil;
+package hirehive.address.testutil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.function.Executable;
diff --git a/src/test/java/hirehive/address/testutil/DefaultPersonBuilder.java b/src/test/java/hirehive/address/testutil/DefaultPersonBuilder.java
new file mode 100644
index 00000000000..9290f040fd2
--- /dev/null
+++ b/src/test/java/hirehive/address/testutil/DefaultPersonBuilder.java
@@ -0,0 +1,46 @@
+package hirehive.address.testutil;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import hirehive.address.model.person.Address;
+import hirehive.address.model.person.Email;
+import hirehive.address.model.person.Name;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.person.Phone;
+import hirehive.address.model.person.Role;
+import hirehive.address.model.tag.Tag;
+
+/**
+ * A utility class to represent default persons added.
+ */
+public class DefaultPersonBuilder {
+
+ public static final String DEFAULT_NAME = "Amy Bee";
+ public static final String DEFAULT_PHONE = "85355255";
+ public static final String DEFAULT_EMAIL = "amy@gmail.com";
+ public static final String DEFAULT_ADDRESS = "123, Jurong West Ave 6, #08-111";
+ public static final String DEFAULT_ROLE = "Software Engineer";
+
+ private Name name;
+ private Phone phone;
+ private Email email;
+ private Address address;
+ private Role role;
+
+ /**
+ * Creates a {@code PersonBuilder} with the default details.
+ */
+ public DefaultPersonBuilder() {
+ name = new Name(DEFAULT_NAME);
+ phone = new Phone(DEFAULT_PHONE);
+ email = new Email(DEFAULT_EMAIL);
+ address = new Address(DEFAULT_ADDRESS);
+ role = new Role(DEFAULT_ROLE);
+ }
+
+ public Person build() {
+ return Person.createDefaultPerson(name, phone, email, address, role);
+ }
+}
+
diff --git a/src/test/java/hirehive/address/testutil/DefaultPersonUtil.java b/src/test/java/hirehive/address/testutil/DefaultPersonUtil.java
new file mode 100644
index 00000000000..b00d0d2b30b
--- /dev/null
+++ b/src/test/java/hirehive/address/testutil/DefaultPersonUtil.java
@@ -0,0 +1,32 @@
+package hirehive.address.testutil;
+
+import hirehive.address.logic.commands.AddCommand;
+import hirehive.address.logic.parser.CliSyntax;
+import hirehive.address.model.person.Person;
+
+/**
+ * A utility class for Default Person.
+ */
+public class DefaultPersonUtil {
+
+ /**
+ * Returns an add command string for adding the {@code person}.
+ */
+ public static String getAddCommand(Person person) {
+ return AddCommand.COMMAND_WORD + " " + getPersonDetails(person);
+ }
+
+ /**
+ * Returns the part of command string for the given {@code person}'s details.
+ */
+ public static String getPersonDetails(Person person) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(CliSyntax.PREFIX_NAME + person.getName().fullName + " ");
+ sb.append(CliSyntax.PREFIX_PHONE + person.getPhone().value + " ");
+ sb.append(CliSyntax.PREFIX_EMAIL + person.getEmail().value + " ");
+ sb.append(CliSyntax.PREFIX_ADDRESS + person.getAddress().value + " ");
+ sb.append(CliSyntax.PREFIX_ROLE + person.getRole().fullRole + " ");
+ return sb.toString();
+ }
+}
+
diff --git a/src/test/java/hirehive/address/testutil/EditPersonDescriptorBuilder.java b/src/test/java/hirehive/address/testutil/EditPersonDescriptorBuilder.java
new file mode 100644
index 00000000000..43a70f970cc
--- /dev/null
+++ b/src/test/java/hirehive/address/testutil/EditPersonDescriptorBuilder.java
@@ -0,0 +1,124 @@
+package hirehive.address.testutil;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import hirehive.address.logic.commands.EditCommand;
+import hirehive.address.logic.parser.ParserUtil;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.Address;
+import hirehive.address.model.person.Email;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.Name;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.person.Phone;
+import hirehive.address.model.person.Role;
+import hirehive.address.model.tag.Tag;
+
+/**
+ * A utility class to help with building EditPersonDescriptor objects.
+ */
+public class EditPersonDescriptorBuilder {
+
+ private EditCommand.EditPersonDescriptor descriptor;
+
+ public EditPersonDescriptorBuilder() {
+ descriptor = new EditCommand.EditPersonDescriptor();
+ }
+
+ public EditPersonDescriptorBuilder(EditCommand.EditPersonDescriptor descriptor) {
+ this.descriptor = new EditCommand.EditPersonDescriptor(descriptor);
+ }
+
+ /**
+ * Returns an {@code EditPersonDescriptor} with fields containing {@code person}'s details
+ */
+ public EditPersonDescriptorBuilder(Person person) {
+ descriptor = new EditCommand.EditPersonDescriptor();
+ descriptor.setName(person.getName());
+ descriptor.setPhone(person.getPhone());
+ descriptor.setEmail(person.getEmail());
+ descriptor.setAddress(person.getAddress());
+ descriptor.setRole(person.getRole());
+ descriptor.setTag(person.getTag());
+ descriptor.setNote(person.getNote());
+ descriptor.setDate(person.getDate());
+ }
+
+ /**
+ * Sets the {@code Name} of the {@code EditPersonDescriptor} that we are building.
+ */
+ public EditPersonDescriptorBuilder withName(String name) {
+ descriptor.setName(new Name(name));
+ return this;
+ }
+
+ /**
+ * Sets the {@code Phone} of the {@code EditPersonDescriptor} that we are building.
+ */
+ public EditPersonDescriptorBuilder withPhone(String phone) {
+ descriptor.setPhone(new Phone(phone));
+ return this;
+ }
+
+ /**
+ * Sets the {@code Email} of the {@code EditPersonDescriptor} that we are building.
+ */
+ public EditPersonDescriptorBuilder withEmail(String email) {
+ descriptor.setEmail(new Email(email));
+ return this;
+ }
+
+ /**
+ * Sets the {@code Address} of the {@code EditPersonDescriptor} that we are building.
+ */
+ public EditPersonDescriptorBuilder withAddress(String address) {
+ descriptor.setAddress(new Address(address));
+ return this;
+ }
+
+ /**
+ * Sets the {@code Role} of the {@code EditPersonDescriptor} that we are building.
+ */
+ public EditPersonDescriptorBuilder withRole(String role) {
+ descriptor.setRole(new Role(role));
+ return this;
+ }
+
+ /**
+ * Sets the {@code Tag} of the {@code EditPersonDescriptor} that we are building.
+ */
+ public EditPersonDescriptorBuilder withTag(String tag) {
+ try {
+ descriptor.setTag(ParserUtil.parseTag(tag));
+ } catch (ParseException e) {
+ // do nothing
+ }
+
+ return this;
+ }
+
+ /**
+ * Sets the {@code Note} of the {@code EditPersonDescriptor} that we are building.
+ */
+ public EditPersonDescriptorBuilder withNote(String note) {
+ descriptor.setNote(new Note(note));
+ return this;
+ }
+
+ /**
+ * Sets the {@code InterviewDate} of the {@code EditPersonDescriptor} that we are building.
+ */
+ public EditPersonDescriptorBuilder withDate(String date) {
+ descriptor.setDate(new InterviewDate(date));
+ return this;
+ }
+
+ public EditCommand.EditPersonDescriptor build() {
+ return descriptor;
+ }
+}
diff --git a/src/test/java/seedu/address/testutil/PersonBuilder.java b/src/test/java/hirehive/address/testutil/PersonBuilder.java
similarity index 50%
rename from src/test/java/seedu/address/testutil/PersonBuilder.java
rename to src/test/java/hirehive/address/testutil/PersonBuilder.java
index 6be381d39ba..a27ac88740a 100644
--- a/src/test/java/seedu/address/testutil/PersonBuilder.java
+++ b/src/test/java/hirehive/address/testutil/PersonBuilder.java
@@ -1,15 +1,19 @@
-package seedu.address.testutil;
+package hirehive.address.testutil;
-import java.util.HashSet;
-import java.util.Set;
+import static hirehive.address.model.tag.Tag.getDefaultTag;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-import seedu.address.model.util.SampleDataUtil;
+import hirehive.address.logic.parser.ParserUtil;
+import hirehive.address.logic.parser.exceptions.ParseException;
+import hirehive.address.model.person.Address;
+import hirehive.address.model.person.Email;
+import hirehive.address.model.person.InterviewDate;
+import hirehive.address.model.person.Name;
+import hirehive.address.model.person.Note;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.person.Phone;
+import hirehive.address.model.person.Role;
+import hirehive.address.model.tag.Tag;
+import hirehive.address.model.util.SampleDataUtil;
/**
* A utility class to help with building Person objects.
@@ -20,12 +24,17 @@ public class PersonBuilder {
public static final String DEFAULT_PHONE = "85355255";
public static final String DEFAULT_EMAIL = "amy@gmail.com";
public static final String DEFAULT_ADDRESS = "123, Jurong West Ave 6, #08-111";
+ public static final String DEFAULT_ROLE = "Software Engineer";
+ public static final String DEFAULT_NOTE = "ENFP personality, no disabilities";
private Name name;
private Phone phone;
private Email email;
private Address address;
- private Set tags;
+ private Role role;
+ private Tag tag;
+ private Note note;
+ private InterviewDate date;
/**
* Creates a {@code PersonBuilder} with the default details.
@@ -35,7 +44,10 @@ public PersonBuilder() {
phone = new Phone(DEFAULT_PHONE);
email = new Email(DEFAULT_EMAIL);
address = new Address(DEFAULT_ADDRESS);
- tags = new HashSet<>();
+ role = new Role(DEFAULT_ROLE);
+ tag = getDefaultTag();
+ note = new Note(DEFAULT_NOTE);
+ date = new InterviewDate();
}
/**
@@ -46,7 +58,10 @@ public PersonBuilder(Person personToCopy) {
phone = personToCopy.getPhone();
email = personToCopy.getEmail();
address = personToCopy.getAddress();
- tags = new HashSet<>(personToCopy.getTags());
+ role = personToCopy.getRole();
+ tag = personToCopy.getTag();
+ note = personToCopy.getNote();
+ date = personToCopy.getDate();
}
/**
@@ -60,8 +75,12 @@ public PersonBuilder withName(String name) {
/**
* Parses the {@code tags} into a {@code Set} and set it to the {@code Person} that we are building.
*/
- public PersonBuilder withTags(String ... tags) {
- this.tags = SampleDataUtil.getTagSet(tags);
+ public PersonBuilder withTag(String tag) {
+ try {
+ this.tag = ParserUtil.parseTag(tag);
+ } catch (ParseException e) {
+ // do nothing
+ }
return this;
}
@@ -89,8 +108,33 @@ public PersonBuilder withEmail(String email) {
return this;
}
+ /**
+ * Sets the {@code Role} of the {@code Role} that we are building.
+ */
+ public PersonBuilder withRole(String role) {
+ this.role = new Role(role);
+ return this;
+ }
+
+ /**
+ * Sets the {@code Note} of the {@code Person} that we are building.
+ */
+ public PersonBuilder withNote(String note) {
+ this.note = new Note(note);
+ return this;
+ }
+
+ /**
+ * Sets the {@code InterviewDate} of the {@code Person} that we are building.
+ */
+ public PersonBuilder withDate(String date) {
+ this.date = new InterviewDate(date);
+ return this;
+ }
+
public Person build() {
- return new Person(name, phone, email, address, tags);
+ return new Person(name, phone, email, address, role, tag, note, date);
}
+
}
diff --git a/src/test/java/hirehive/address/testutil/PersonUtil.java b/src/test/java/hirehive/address/testutil/PersonUtil.java
new file mode 100644
index 00000000000..8ff875c5097
--- /dev/null
+++ b/src/test/java/hirehive/address/testutil/PersonUtil.java
@@ -0,0 +1,54 @@
+package hirehive.address.testutil;
+
+import java.util.Set;
+
+import hirehive.address.logic.commands.AddCommand;
+import hirehive.address.logic.commands.EditCommand;
+import hirehive.address.logic.parser.CliSyntax;
+import hirehive.address.model.person.Person;
+import hirehive.address.model.tag.Tag;
+
+/**
+ * A utility class for Person.
+ */
+public class PersonUtil {
+
+ /**
+ * Returns an add command string for adding the {@code person}.
+ */
+ public static String getAddCommand(Person person) {
+ return AddCommand.COMMAND_WORD + " " + getPersonDetails(person);
+ }
+
+ /**
+ * Returns the part of command string for the given {@code person}'s details.
+ */
+ public static String getPersonDetails(Person person) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(CliSyntax.PREFIX_NAME + person.getName().fullName + " ");
+ sb.append(CliSyntax.PREFIX_PHONE + person.getPhone().value + " ");
+ sb.append(CliSyntax.PREFIX_EMAIL + person.getEmail().value + " ");
+ sb.append(CliSyntax.PREFIX_ADDRESS + person.getAddress().value + " ");
+ sb.append(CliSyntax.PREFIX_ROLE + person.getRole().fullRole + " ");
+ sb.append(CliSyntax.PREFIX_TAG + person.getTag().getTagName() + " ");
+ sb.append(CliSyntax.PREFIX_NOTE + person.getNote().value + " ");
+ sb.append(CliSyntax.PREFIX_DATE + person.getDate().toString() + " ");
+ return sb.toString();
+ }
+
+ /**
+ * Returns the part of command string for the given {@code EditPersonDescriptor}'s details.
+ */
+ public static String getEditPersonDescriptorDetails(EditCommand.EditPersonDescriptor descriptor) {
+ StringBuilder sb = new StringBuilder();
+ descriptor.getName().ifPresent(name -> sb.append(CliSyntax.PREFIX_NAME).append(name.fullName).append(" "));
+ descriptor.getPhone().ifPresent(phone -> sb.append(CliSyntax.PREFIX_PHONE).append(phone.value).append(" "));
+ descriptor.getEmail().ifPresent(email -> sb.append(CliSyntax.PREFIX_EMAIL).append(email.value).append(" "));
+ descriptor.getAddress().ifPresent(address -> sb.append(CliSyntax.PREFIX_ADDRESS).append(address.value).append(" "));
+ descriptor.getRole().ifPresent(role -> sb.append(CliSyntax.PREFIX_ROLE).append(role.fullRole).append(" "));
+ descriptor.getNote().ifPresent(note -> sb.append(CliSyntax.PREFIX_NOTE).append(note.value).append(" "));
+ descriptor.getTag().ifPresent(tag -> sb.append(CliSyntax.PREFIX_TAG).append(tag.getTagName()).append(" "));
+ descriptor.getDate().ifPresent(date -> sb.append(CliSyntax.PREFIX_DATE).append(date.toString()).append(" "));
+ return sb.toString();
+ }
+}
diff --git a/src/test/java/seedu/address/testutil/SerializableTestClass.java b/src/test/java/hirehive/address/testutil/SerializableTestClass.java
similarity index 98%
rename from src/test/java/seedu/address/testutil/SerializableTestClass.java
rename to src/test/java/hirehive/address/testutil/SerializableTestClass.java
index f5a66340489..4f11e81af86 100644
--- a/src/test/java/seedu/address/testutil/SerializableTestClass.java
+++ b/src/test/java/hirehive/address/testutil/SerializableTestClass.java
@@ -1,4 +1,4 @@
-package seedu.address.testutil;
+package hirehive.address.testutil;
import java.time.LocalDateTime;
import java.util.ArrayList;
diff --git a/src/test/java/seedu/address/testutil/TestUtil.java b/src/test/java/hirehive/address/testutil/TestUtil.java
similarity index 90%
rename from src/test/java/seedu/address/testutil/TestUtil.java
rename to src/test/java/hirehive/address/testutil/TestUtil.java
index 896d103eb0b..7a2c08e80e5 100644
--- a/src/test/java/seedu/address/testutil/TestUtil.java
+++ b/src/test/java/hirehive/address/testutil/TestUtil.java
@@ -1,13 +1,13 @@
-package seedu.address.testutil;
+package hirehive.address.testutil;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import seedu.address.commons.core.index.Index;
-import seedu.address.model.Model;
-import seedu.address.model.person.Person;
+import hirehive.address.commons.core.index.Index;
+import hirehive.address.model.Model;
+import hirehive.address.model.person.Person;
/**
* A utility class for test cases.
diff --git a/src/test/java/seedu/address/testutil/TypicalIndexes.java b/src/test/java/hirehive/address/testutil/TypicalIndexes.java
similarity index 80%
rename from src/test/java/seedu/address/testutil/TypicalIndexes.java
rename to src/test/java/hirehive/address/testutil/TypicalIndexes.java
index 1e613937657..86ebe45e98b 100644
--- a/src/test/java/seedu/address/testutil/TypicalIndexes.java
+++ b/src/test/java/hirehive/address/testutil/TypicalIndexes.java
@@ -1,6 +1,6 @@
-package seedu.address.testutil;
+package hirehive.address.testutil;
-import seedu.address.commons.core.index.Index;
+import hirehive.address.commons.core.index.Index;
/**
* A utility class containing a list of {@code Index} objects to be used in tests.
diff --git a/src/test/java/seedu/address/testutil/TypicalPersons.java b/src/test/java/hirehive/address/testutil/TypicalPersons.java
similarity index 50%
rename from src/test/java/seedu/address/testutil/TypicalPersons.java
rename to src/test/java/hirehive/address/testutil/TypicalPersons.java
index fec76fb7129..fe578b91a38 100644
--- a/src/test/java/seedu/address/testutil/TypicalPersons.java
+++ b/src/test/java/hirehive/address/testutil/TypicalPersons.java
@@ -1,22 +1,25 @@
-package seedu.address.testutil;
+package hirehive.address.testutil;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
+import static hirehive.address.logic.commands.CommandTestUtil.DEFAULT_TAG_APPLICANT;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_ADDRESS_AMY;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_NAME_AMY;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_NOTE_AMY;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_NOTE_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_PHONE_AMY;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_ROLE_AMY;
+import static hirehive.address.logic.commands.CommandTestUtil.VALID_ROLE_BOB;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import seedu.address.model.AddressBook;
-import seedu.address.model.person.Person;
+import hirehive.address.model.AddressBook;
+import hirehive.address.model.person.Person;
/**
* A utility class containing a list of {@code Person} objects to be used in tests.
@@ -25,35 +28,42 @@ public class TypicalPersons {
public static final Person ALICE = new PersonBuilder().withName("Alice Pauline")
.withAddress("123, Jurong West Ave 6, #08-111").withEmail("alice@example.com")
- .withPhone("94351253")
- .withTags("friends").build();
+ .withPhone("94351253").withRole("Software Engineer")
+ .withTag("Applicant").withNote("Shy").withDate("").build();
public static final Person BENSON = new PersonBuilder().withName("Benson Meier")
.withAddress("311, Clementi Ave 2, #02-25")
- .withEmail("johnd@example.com").withPhone("98765432")
- .withTags("owesMoney", "friends").build();
+ .withEmail("johnd@example.com").withPhone("98765432").withRole("Software Engineer")
+ .withTag("Rejected").withNote("6 foot tall").withDate("01/02/2025").build();
public static final Person CARL = new PersonBuilder().withName("Carl Kurz").withPhone("95352563")
- .withEmail("heinz@example.com").withAddress("wall street").build();
+ .withEmail("heinz@example.com").withAddress("wall street").withRole("Software Engineer")
+ .withTag("Interviewee").withNote("Only 18 years old").withDate("01/04/2025").build();
public static final Person DANIEL = new PersonBuilder().withName("Daniel Meier").withPhone("87652533")
- .withEmail("cornelia@example.com").withAddress("10th street").withTags("friends").build();
- public static final Person ELLE = new PersonBuilder().withName("Elle Meyer").withPhone("9482224")
- .withEmail("werner@example.com").withAddress("michegan ave").build();
- public static final Person FIONA = new PersonBuilder().withName("Fiona Kunz").withPhone("9482427")
- .withEmail("lydia@example.com").withAddress("little tokyo").build();
- public static final Person GEORGE = new PersonBuilder().withName("George Best").withPhone("9482442")
- .withEmail("anna@example.com").withAddress("4th street").build();
-
+ .withEmail("cornelia@example.com").withAddress("10th street").withRole("Software Engineer")
+ .withTag("Applicant").withNote("Funny").withDate("").build();
+ public static final Person ELLE = new PersonBuilder().withName("Elle Meyer").withPhone("94822243")
+ .withEmail("werner@example.com").withAddress("michegan ave").withRole("Software Engineer")
+ .withTag("Rejected").withNote("Cheerful").withDate("01/03/2025").build();
+ public static final Person FIONA = new PersonBuilder().withName("Fiona Kunz").withPhone("94824273")
+ .withEmail("lydia@example.com").withAddress("little tokyo").withRole("Software Engineer")
+ .withTag("Rejected").withNote("Scary").withDate("01/03/2025").build();
+ public static final Person GEORGE = new PersonBuilder().withName("George Best").withPhone("94824421")
+ .withEmail("anna@example.com").withAddress("4th street").withRole("Software Engineer")
+ .withTag("Applicant").withNote("Fat").withDate("").build();
// Manually added
- public static final Person HOON = new PersonBuilder().withName("Hoon Meier").withPhone("8482424")
- .withEmail("stefan@example.com").withAddress("little india").build();
- public static final Person IDA = new PersonBuilder().withName("Ida Mueller").withPhone("8482131")
- .withEmail("hans@example.com").withAddress("chicago ave").build();
+ public static final Person HOON = new PersonBuilder().withName("Hoon Meier").withPhone("84824246")
+ .withEmail("stefan@example.com").withAddress("little india").withRole("Software Engineer")
+ .withNote("Skinny").build();
+ public static final Person IDA = new PersonBuilder().withName("Ida Mueller").withPhone("84821312")
+ .withEmail("hans@example.com").withAddress("chicago ave").withRole("Software Engineer")
+ .withNote("Has criminal record").build();
// Manually added - Person's details found in {@code CommandTestUtil}
public static final Person AMY = new PersonBuilder().withName(VALID_NAME_AMY).withPhone(VALID_PHONE_AMY)
- .withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY).withTags(VALID_TAG_FRIEND).build();
+ .withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY).withRole(VALID_ROLE_AMY)
+ .withTag(DEFAULT_TAG_APPLICANT).withNote(VALID_NOTE_AMY).build();
public static final Person BOB = new PersonBuilder().withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB)
- .withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND)
- .build();
+ .withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB).withRole(VALID_ROLE_BOB)
+ .withTag(DEFAULT_TAG_APPLICANT).withNote(VALID_NOTE_BOB).build();
public static final String KEYWORD_MATCHING_MEIER = "Meier"; // A keyword that matches MEIER
diff --git a/src/test/java/seedu/address/ui/TestFxmlObject.java b/src/test/java/hirehive/address/ui/TestFxmlObject.java
similarity index 97%
rename from src/test/java/seedu/address/ui/TestFxmlObject.java
rename to src/test/java/hirehive/address/ui/TestFxmlObject.java
index 93f40f1276a..6e556df24ac 100644
--- a/src/test/java/seedu/address/ui/TestFxmlObject.java
+++ b/src/test/java/hirehive/address/ui/TestFxmlObject.java
@@ -1,4 +1,4 @@
-package seedu.address.ui;
+package hirehive.address.ui;
import java.util.Objects;
diff --git a/src/test/java/seedu/address/ui/UiPartTest.java b/src/test/java/hirehive/address/ui/UiPartTest.java
similarity index 97%
rename from src/test/java/seedu/address/ui/UiPartTest.java
rename to src/test/java/hirehive/address/ui/UiPartTest.java
index 33d82d911b8..82926b62e8b 100644
--- a/src/test/java/seedu/address/ui/UiPartTest.java
+++ b/src/test/java/hirehive/address/ui/UiPartTest.java
@@ -1,8 +1,8 @@
-package seedu.address.ui;
+package hirehive.address.ui;
+import static hirehive.address.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static seedu.address.testutil.Assert.assertThrows;
import java.net.URL;
import java.nio.file.Path;
@@ -10,8 +10,8 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
+import hirehive.address.MainApp;
import javafx.fxml.FXML;
-import seedu.address.MainApp;
public class UiPartTest {
diff --git a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java
deleted file mode 100644
index 162a0c86031..00000000000
--- a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package seedu.address.logic.commands;
-
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import seedu.address.logic.Messages;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.UserPrefs;
-import seedu.address.model.person.Person;
-import seedu.address.testutil.PersonBuilder;
-
-/**
- * Contains integration tests (interaction with the Model) for {@code AddCommand}.
- */
-public class AddCommandIntegrationTest {
-
- private Model model;
-
- @BeforeEach
- public void setUp() {
- model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
- }
-
- @Test
- public void execute_newPerson_success() {
- Person validPerson = new PersonBuilder().build();
-
- Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
- expectedModel.addPerson(validPerson);
-
- assertCommandSuccess(new AddCommand(validPerson), model,
- String.format(AddCommand.MESSAGE_SUCCESS, Messages.format(validPerson)),
- expectedModel);
- }
-
- @Test
- public void execute_duplicatePerson_throwsCommandException() {
- Person personInList = model.getAddressBook().getPersonList().get(0);
- assertCommandFailure(new AddCommand(personInList), model,
- AddCommand.MESSAGE_DUPLICATE_PERSON);
- }
-
-}
diff --git a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java
deleted file mode 100644
index 80d9110c03a..00000000000
--- a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package seedu.address.logic.commands;
-
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
-
-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.UserPrefs;
-
-public class ClearCommandTest {
-
- @Test
- public void execute_emptyAddressBook_success() {
- Model model = new ModelManager();
- Model expectedModel = new ModelManager();
-
- assertCommandSuccess(new ClearCommand(), model, ClearCommand.MESSAGE_SUCCESS, expectedModel);
- }
-
- @Test
- public void execute_nonEmptyAddressBook_success() {
- Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
- Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs());
- expectedModel.setAddressBook(new AddressBook());
-
- assertCommandSuccess(new ClearCommand(), model, ClearCommand.MESSAGE_SUCCESS, expectedModel);
- }
-
-}
diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java
deleted file mode 100644
index 643a1d08069..00000000000
--- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java
+++ /dev/null
@@ -1,128 +0,0 @@
-package seedu.address.logic.commands;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-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_PHONE;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
-import static seedu.address.testutil.Assert.assertThrows;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import seedu.address.commons.core.index.Index;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.model.AddressBook;
-import seedu.address.model.Model;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
-import seedu.address.model.person.Person;
-import seedu.address.testutil.EditPersonDescriptorBuilder;
-
-/**
- * Contains helper methods for testing commands.
- */
-public class CommandTestUtil {
-
- public static final String VALID_NAME_AMY = "Amy Bee";
- public static final String VALID_NAME_BOB = "Bob Choo";
- public static final String VALID_PHONE_AMY = "11111111";
- public static final String VALID_PHONE_BOB = "22222222";
- public static final String VALID_EMAIL_AMY = "amy@example.com";
- public static final String VALID_EMAIL_BOB = "bob@example.com";
- public static final String VALID_ADDRESS_AMY = "Block 312, Amy Street 1";
- 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 NAME_DESC_AMY = " " + PREFIX_NAME + VALID_NAME_AMY;
- public static final String NAME_DESC_BOB = " " + PREFIX_NAME + VALID_NAME_BOB;
- public static final String PHONE_DESC_AMY = " " + PREFIX_PHONE + VALID_PHONE_AMY;
- public static final String PHONE_DESC_BOB = " " + PREFIX_PHONE + VALID_PHONE_BOB;
- public static final String EMAIL_DESC_AMY = " " + PREFIX_EMAIL + VALID_EMAIL_AMY;
- public static final String EMAIL_DESC_BOB = " " + PREFIX_EMAIL + VALID_EMAIL_BOB;
- public static final String ADDRESS_DESC_AMY = " " + PREFIX_ADDRESS + VALID_ADDRESS_AMY;
- 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 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
- public static final String INVALID_EMAIL_DESC = " " + PREFIX_EMAIL + "bob!yahoo"; // missing '@' symbol
- public static final String INVALID_ADDRESS_DESC = " " + PREFIX_ADDRESS; // empty string not allowed for addresses
- public static final String INVALID_TAG_DESC = " " + PREFIX_TAG + "hubby*"; // '*' not allowed in tags
-
- public static final String PREAMBLE_WHITESPACE = "\t \r \n";
- public static final String PREAMBLE_NON_EMPTY = "NonEmptyPreamble";
-
- public static final EditCommand.EditPersonDescriptor DESC_AMY;
- public static final EditCommand.EditPersonDescriptor DESC_BOB;
-
- static {
- DESC_AMY = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY)
- .withPhone(VALID_PHONE_AMY).withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY)
- .withTags(VALID_TAG_FRIEND).build();
- DESC_BOB = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB)
- .withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB)
- .withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND).build();
- }
-
- /**
- * Executes the given {@code command}, confirms that
- * - the returned {@link CommandResult} matches {@code expectedCommandResult}
- * - the {@code actualModel} matches {@code expectedModel}
- */
- public static void assertCommandSuccess(Command command, Model actualModel, CommandResult expectedCommandResult,
- Model expectedModel) {
- try {
- CommandResult result = command.execute(actualModel);
- assertEquals(expectedCommandResult, result);
- assertEquals(expectedModel, actualModel);
- } catch (CommandException ce) {
- throw new AssertionError("Execution of command should not fail.", ce);
- }
- }
-
- /**
- * Convenience wrapper to {@link #assertCommandSuccess(Command, Model, CommandResult, Model)}
- * that takes a string {@code expectedMessage}.
- */
- public static void assertCommandSuccess(Command command, Model actualModel, String expectedMessage,
- Model expectedModel) {
- CommandResult expectedCommandResult = new CommandResult(expectedMessage);
- assertCommandSuccess(command, actualModel, expectedCommandResult, expectedModel);
- }
-
- /**
- * Executes the given {@code command}, confirms that
- * - a {@code CommandException} is thrown
- * - the CommandException message matches {@code expectedMessage}
- * - the address book, filtered person list and selected person in {@code actualModel} remain unchanged
- */
- public static void assertCommandFailure(Command command, Model actualModel, String expectedMessage) {
- // we are unable to defensively copy the model for comparison later, so we can
- // only do so by copying its components.
- AddressBook expectedAddressBook = new AddressBook(actualModel.getAddressBook());
- List expectedFilteredList = new ArrayList<>(actualModel.getFilteredPersonList());
-
- assertThrows(CommandException.class, expectedMessage, () -> command.execute(actualModel));
- assertEquals(expectedAddressBook, actualModel.getAddressBook());
- assertEquals(expectedFilteredList, actualModel.getFilteredPersonList());
- }
- /**
- * Updates {@code model}'s filtered list to show only the person at the given {@code targetIndex} in the
- * {@code model}'s address book.
- */
- public static void showPersonAtIndex(Model model, Index targetIndex) {
- assertTrue(targetIndex.getZeroBased() < model.getFilteredPersonList().size());
-
- Person person = model.getFilteredPersonList().get(targetIndex.getZeroBased());
- final String[] splitName = person.getName().fullName.split("\\s+");
- model.updateFilteredPersonList(new NameContainsKeywordsPredicate(Arrays.asList(splitName[0])));
-
- assertEquals(1, model.getFilteredPersonList().size());
- }
-
-}
diff --git a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java
deleted file mode 100644
index b6f332eabca..00000000000
--- a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package seedu.address.logic.commands;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.commons.core.index.Index;
-import seedu.address.logic.Messages;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.UserPrefs;
-import seedu.address.model.person.Person;
-
-/**
- * Contains integration tests (interaction with the Model) and unit tests for
- * {@code DeleteCommand}.
- */
-public class DeleteCommandTest {
-
- private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
-
- @Test
- public void execute_validIndexUnfilteredList_success() {
- Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
- DeleteCommand deleteCommand = new DeleteCommand(INDEX_FIRST_PERSON);
-
- String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS,
- Messages.format(personToDelete));
-
- ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
- expectedModel.deletePerson(personToDelete);
-
- assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel);
- }
-
- @Test
- public void execute_invalidIndexUnfilteredList_throwsCommandException() {
- Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1);
- DeleteCommand deleteCommand = new DeleteCommand(outOfBoundIndex);
-
- assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
- }
-
- @Test
- public void execute_validIndexFilteredList_success() {
- showPersonAtIndex(model, INDEX_FIRST_PERSON);
-
- Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
- DeleteCommand deleteCommand = new DeleteCommand(INDEX_FIRST_PERSON);
-
- String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS,
- Messages.format(personToDelete));
-
- Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
- expectedModel.deletePerson(personToDelete);
- showNoPerson(expectedModel);
-
- assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel);
- }
-
- @Test
- public void execute_invalidIndexFilteredList_throwsCommandException() {
- showPersonAtIndex(model, INDEX_FIRST_PERSON);
-
- Index outOfBoundIndex = INDEX_SECOND_PERSON;
- // ensures that outOfBoundIndex is still in bounds of address book list
- assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size());
-
- DeleteCommand deleteCommand = new DeleteCommand(outOfBoundIndex);
-
- assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
- }
-
- @Test
- public void equals() {
- DeleteCommand deleteFirstCommand = new DeleteCommand(INDEX_FIRST_PERSON);
- DeleteCommand deleteSecondCommand = new DeleteCommand(INDEX_SECOND_PERSON);
-
- // same object -> returns true
- assertTrue(deleteFirstCommand.equals(deleteFirstCommand));
-
- // same values -> returns true
- DeleteCommand deleteFirstCommandCopy = new DeleteCommand(INDEX_FIRST_PERSON);
- assertTrue(deleteFirstCommand.equals(deleteFirstCommandCopy));
-
- // different types -> returns false
- assertFalse(deleteFirstCommand.equals(1));
-
- // null -> returns false
- assertFalse(deleteFirstCommand.equals(null));
-
- // different person -> returns false
- assertFalse(deleteFirstCommand.equals(deleteSecondCommand));
- }
-
- @Test
- public void toStringMethod() {
- Index targetIndex = Index.fromOneBased(1);
- DeleteCommand deleteCommand = new DeleteCommand(targetIndex);
- String expected = DeleteCommand.class.getCanonicalName() + "{targetIndex=" + targetIndex + "}";
- assertEquals(expected, deleteCommand.toString());
- }
-
- /**
- * Updates {@code model}'s filtered list to show no one.
- */
- private void showNoPerson(Model model) {
- model.updateFilteredPersonList(p -> false);
-
- assertTrue(model.getFilteredPersonList().isEmpty());
- }
-}
diff --git a/src/test/java/seedu/address/logic/commands/FindCommandTest.java b/src/test/java/seedu/address/logic/commands/FindCommandTest.java
deleted file mode 100644
index b8b7dbba91a..00000000000
--- a/src/test/java/seedu/address/logic/commands/FindCommandTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package seedu.address.logic.commands;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.testutil.TypicalPersons.CARL;
-import static seedu.address.testutil.TypicalPersons.ELLE;
-import static seedu.address.testutil.TypicalPersons.FIONA;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.UserPrefs;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
-
-/**
- * Contains integration tests (interaction with the Model) for {@code FindCommand}.
- */
-public class FindCommandTest {
- private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
- private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs());
-
- @Test
- public void equals() {
- NameContainsKeywordsPredicate firstPredicate =
- new NameContainsKeywordsPredicate(Collections.singletonList("first"));
- NameContainsKeywordsPredicate secondPredicate =
- new NameContainsKeywordsPredicate(Collections.singletonList("second"));
-
- FindCommand findFirstCommand = new FindCommand(firstPredicate);
- FindCommand findSecondCommand = new FindCommand(secondPredicate);
-
- // same object -> returns true
- assertTrue(findFirstCommand.equals(findFirstCommand));
-
- // same values -> returns true
- FindCommand findFirstCommandCopy = new FindCommand(firstPredicate);
- assertTrue(findFirstCommand.equals(findFirstCommandCopy));
-
- // different types -> returns false
- assertFalse(findFirstCommand.equals(1));
-
- // null -> returns false
- assertFalse(findFirstCommand.equals(null));
-
- // different person -> returns false
- assertFalse(findFirstCommand.equals(findSecondCommand));
- }
-
- @Test
- public void execute_zeroKeywords_noPersonFound() {
- String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0);
- NameContainsKeywordsPredicate predicate = preparePredicate(" ");
- FindCommand command = new FindCommand(predicate);
- expectedModel.updateFilteredPersonList(predicate);
- assertCommandSuccess(command, model, expectedMessage, expectedModel);
- assertEquals(Collections.emptyList(), model.getFilteredPersonList());
- }
-
- @Test
- public void execute_multipleKeywords_multiplePersonsFound() {
- String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 3);
- NameContainsKeywordsPredicate predicate = preparePredicate("Kurz Elle Kunz");
- FindCommand command = new FindCommand(predicate);
- expectedModel.updateFilteredPersonList(predicate);
- assertCommandSuccess(command, model, expectedMessage, expectedModel);
- assertEquals(Arrays.asList(CARL, ELLE, FIONA), model.getFilteredPersonList());
- }
-
- @Test
- public void toStringMethod() {
- NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Arrays.asList("keyword"));
- FindCommand findCommand = new FindCommand(predicate);
- String expected = FindCommand.class.getCanonicalName() + "{predicate=" + predicate + "}";
- assertEquals(expected, findCommand.toString());
- }
-
- /**
- * Parses {@code userInput} into a {@code NameContainsKeywordsPredicate}.
- */
- private NameContainsKeywordsPredicate preparePredicate(String userInput) {
- return new NameContainsKeywordsPredicate(Arrays.asList(userInput.split("\\s+")));
- }
-}
diff --git a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java
deleted file mode 100644
index 5bc11d3cdaa..00000000000
--- a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package seedu.address.logic.parser;
-
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_ADDRESS_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_EMAIL_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_NAME_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_PHONE_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_TAG_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.PREAMBLE_NON_EMPTY;
-import static seedu.address.logic.commands.CommandTestUtil.PREAMBLE_WHITESPACE;
-import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_FRIEND;
-import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_HUSBAND;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-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.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_PHONE;
-import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
-import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;
-import static seedu.address.testutil.TypicalPersons.AMY;
-import static seedu.address.testutil.TypicalPersons.BOB;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.logic.Messages;
-import seedu.address.logic.commands.AddCommand;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-import seedu.address.testutil.PersonBuilder;
-
-public class AddCommandParserTest {
- private AddCommandParser parser = new AddCommandParser();
-
- @Test
- public void parse_allFieldsPresent_success() {
- Person expectedPerson = new PersonBuilder(BOB).withTags(VALID_TAG_FRIEND).build();
-
- // whitespace only preamble
- assertParseSuccess(parser, PREAMBLE_WHITESPACE + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB
- + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedPerson));
-
-
- // multiple tags - all accepted
- Person expectedPersonMultipleTags = new PersonBuilder(BOB).withTags(VALID_TAG_FRIEND, VALID_TAG_HUSBAND)
- .build();
- assertParseSuccess(parser,
- NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB + TAG_DESC_HUSBAND + TAG_DESC_FRIEND,
- new AddCommand(expectedPersonMultipleTags));
- }
-
- @Test
- public void parse_repeatedNonTagValue_failure() {
- String validExpectedPersonString = NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB
- + ADDRESS_DESC_BOB + TAG_DESC_FRIEND;
-
- // multiple names
- assertParseFailure(parser, NAME_DESC_AMY + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NAME));
-
- // multiple phones
- assertParseFailure(parser, PHONE_DESC_AMY + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE));
-
- // multiple emails
- assertParseFailure(parser, EMAIL_DESC_AMY + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_EMAIL));
-
- // multiple addresses
- assertParseFailure(parser, ADDRESS_DESC_AMY + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_ADDRESS));
-
- // multiple fields repeated
- assertParseFailure(parser,
- validExpectedPersonString + PHONE_DESC_AMY + EMAIL_DESC_AMY + NAME_DESC_AMY + ADDRESS_DESC_AMY
- + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NAME, PREFIX_ADDRESS, PREFIX_EMAIL, PREFIX_PHONE));
-
- // invalid value followed by valid value
-
- // invalid name
- assertParseFailure(parser, INVALID_NAME_DESC + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NAME));
-
- // invalid email
- assertParseFailure(parser, INVALID_EMAIL_DESC + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_EMAIL));
-
- // invalid phone
- assertParseFailure(parser, INVALID_PHONE_DESC + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE));
-
- // invalid address
- assertParseFailure(parser, INVALID_ADDRESS_DESC + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_ADDRESS));
-
- // valid value followed by invalid value
-
- // invalid name
- assertParseFailure(parser, validExpectedPersonString + INVALID_NAME_DESC,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NAME));
-
- // invalid email
- assertParseFailure(parser, validExpectedPersonString + INVALID_EMAIL_DESC,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_EMAIL));
-
- // invalid phone
- assertParseFailure(parser, validExpectedPersonString + INVALID_PHONE_DESC,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE));
-
- // invalid address
- assertParseFailure(parser, validExpectedPersonString + INVALID_ADDRESS_DESC,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_ADDRESS));
- }
-
- @Test
- public void parse_optionalFieldsMissing_success() {
- // zero tags
- Person expectedPerson = new PersonBuilder(AMY).withTags().build();
- assertParseSuccess(parser, NAME_DESC_AMY + PHONE_DESC_AMY + EMAIL_DESC_AMY + ADDRESS_DESC_AMY,
- new AddCommand(expectedPerson));
- }
-
- @Test
- public void parse_compulsoryFieldMissing_failure() {
- String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE);
-
- // missing name prefix
- assertParseFailure(parser, VALID_NAME_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB,
- expectedMessage);
-
- // missing phone prefix
- assertParseFailure(parser, NAME_DESC_BOB + VALID_PHONE_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB,
- expectedMessage);
-
- // missing email prefix
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + VALID_EMAIL_BOB + ADDRESS_DESC_BOB,
- expectedMessage);
-
- // missing address prefix
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + VALID_ADDRESS_BOB,
- expectedMessage);
-
- // all prefixes missing
- assertParseFailure(parser, VALID_NAME_BOB + VALID_PHONE_BOB + VALID_EMAIL_BOB + VALID_ADDRESS_BOB,
- expectedMessage);
- }
-
- @Test
- public void parse_invalidValue_failure() {
- // invalid name
- assertParseFailure(parser, INVALID_NAME_DESC + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB
- + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Name.MESSAGE_CONSTRAINTS);
-
- // invalid phone
- assertParseFailure(parser, NAME_DESC_BOB + INVALID_PHONE_DESC + EMAIL_DESC_BOB + ADDRESS_DESC_BOB
- + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Phone.MESSAGE_CONSTRAINTS);
-
- // invalid email
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + INVALID_EMAIL_DESC + ADDRESS_DESC_BOB
- + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Email.MESSAGE_CONSTRAINTS);
-
- // invalid address
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + INVALID_ADDRESS_DESC
- + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Address.MESSAGE_CONSTRAINTS);
-
- // invalid tag
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB
- + INVALID_TAG_DESC + VALID_TAG_FRIEND, Tag.MESSAGE_CONSTRAINTS);
-
- // two invalid values, only first invalid value reported
- assertParseFailure(parser, INVALID_NAME_DESC + PHONE_DESC_BOB + EMAIL_DESC_BOB + INVALID_ADDRESS_DESC,
- Name.MESSAGE_CONSTRAINTS);
-
- // non-empty preamble
- assertParseFailure(parser, PREAMBLE_NON_EMPTY + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB
- + ADDRESS_DESC_BOB + TAG_DESC_HUSBAND + TAG_DESC_FRIEND,
- String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));
- }
-}
diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java
deleted file mode 100644
index 5a1ab3dbc0c..00000000000
--- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package seedu.address.logic.parser;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.Messages.MESSAGE_UNKNOWN_COMMAND;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.logic.commands.AddCommand;
-import seedu.address.logic.commands.ClearCommand;
-import seedu.address.logic.commands.DeleteCommand;
-import seedu.address.logic.commands.EditCommand;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.logic.commands.ExitCommand;
-import seedu.address.logic.commands.FindCommand;
-import seedu.address.logic.commands.HelpCommand;
-import seedu.address.logic.commands.ListCommand;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
-import seedu.address.model.person.Person;
-import seedu.address.testutil.EditPersonDescriptorBuilder;
-import seedu.address.testutil.PersonBuilder;
-import seedu.address.testutil.PersonUtil;
-
-public class AddressBookParserTest {
-
- private final AddressBookParser parser = new AddressBookParser();
-
- @Test
- public void parseCommand_add() throws Exception {
- Person person = new PersonBuilder().build();
- AddCommand command = (AddCommand) parser.parseCommand(PersonUtil.getAddCommand(person));
- assertEquals(new AddCommand(person), command);
- }
-
- @Test
- public void parseCommand_clear() throws Exception {
- assertTrue(parser.parseCommand(ClearCommand.COMMAND_WORD) instanceof ClearCommand);
- assertTrue(parser.parseCommand(ClearCommand.COMMAND_WORD + " 3") instanceof ClearCommand);
- }
-
- @Test
- public void parseCommand_delete() throws Exception {
- DeleteCommand command = (DeleteCommand) parser.parseCommand(
- DeleteCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased());
- assertEquals(new DeleteCommand(INDEX_FIRST_PERSON), command);
- }
-
- @Test
- public void parseCommand_edit() throws Exception {
- Person person = new PersonBuilder().build();
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(person).build();
- EditCommand command = (EditCommand) parser.parseCommand(EditCommand.COMMAND_WORD + " "
- + INDEX_FIRST_PERSON.getOneBased() + " " + PersonUtil.getEditPersonDescriptorDetails(descriptor));
- assertEquals(new EditCommand(INDEX_FIRST_PERSON, descriptor), command);
- }
-
- @Test
- public void parseCommand_exit() throws Exception {
- assertTrue(parser.parseCommand(ExitCommand.COMMAND_WORD) instanceof ExitCommand);
- assertTrue(parser.parseCommand(ExitCommand.COMMAND_WORD + " 3") instanceof ExitCommand);
- }
-
- @Test
- public void parseCommand_find() throws Exception {
- List keywords = Arrays.asList("foo", "bar", "baz");
- FindCommand command = (FindCommand) parser.parseCommand(
- FindCommand.COMMAND_WORD + " " + keywords.stream().collect(Collectors.joining(" ")));
- assertEquals(new FindCommand(new NameContainsKeywordsPredicate(keywords)), command);
- }
-
- @Test
- public void parseCommand_help() throws Exception {
- assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD) instanceof HelpCommand);
- assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD + " 3") instanceof HelpCommand);
- }
-
- @Test
- public void parseCommand_list() throws Exception {
- assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD) instanceof ListCommand);
- assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD + " 3") instanceof ListCommand);
- }
-
- @Test
- public void parseCommand_unrecognisedInput_throwsParseException() {
- assertThrows(ParseException.class, String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE), ()
- -> parser.parseCommand(""));
- }
-
- @Test
- public void parseCommand_unknownCommand_throwsParseException() {
- assertThrows(ParseException.class, MESSAGE_UNKNOWN_COMMAND, () -> parser.parseCommand("unknownCommand"));
- }
-}
diff --git a/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java
deleted file mode 100644
index 6a40e14a649..00000000000
--- a/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package seedu.address.logic.parser;
-
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
-import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.logic.commands.DeleteCommand;
-
-/**
- * As we are only doing white-box testing, our test cases do not cover path variations
- * outside of the DeleteCommand code. For example, inputs "1" and "1 abc" take the
- * same path through the DeleteCommand, and therefore we test only one of them.
- * The path variation for those two cases occur inside the ParserUtil, and
- * therefore should be covered by the ParserUtilTest.
- */
-public class DeleteCommandParserTest {
-
- private DeleteCommandParser parser = new DeleteCommandParser();
-
- @Test
- public void parse_validArgs_returnsDeleteCommand() {
- assertParseSuccess(parser, "1", new DeleteCommand(INDEX_FIRST_PERSON));
- }
-
- @Test
- public void parse_invalidArgs_throwsParseException() {
- assertParseFailure(parser, "a", String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE));
- }
-}
diff --git a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java b/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java
deleted file mode 100644
index cc7175172d4..00000000000
--- a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java
+++ /dev/null
@@ -1,208 +0,0 @@
-package seedu.address.logic.parser;
-
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_ADDRESS_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_EMAIL_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_NAME_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_PHONE_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_TAG_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_FRIEND;
-import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_HUSBAND;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-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.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
-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_PERSON;
-import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON;
-import static seedu.address.testutil.TypicalIndexes.INDEX_THIRD_PERSON;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.commons.core.index.Index;
-import seedu.address.logic.Messages;
-import seedu.address.logic.commands.EditCommand;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-import seedu.address.testutil.EditPersonDescriptorBuilder;
-
-public class EditCommandParserTest {
-
- private static final String TAG_EMPTY = " " + PREFIX_TAG;
-
- private static final String MESSAGE_INVALID_FORMAT =
- String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE);
-
- private EditCommandParser parser = new EditCommandParser();
-
- @Test
- public void parse_missingParts_failure() {
- // no index specified
- assertParseFailure(parser, VALID_NAME_AMY, MESSAGE_INVALID_FORMAT);
-
- // no field specified
- assertParseFailure(parser, "1", EditCommand.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_AMY, MESSAGE_INVALID_FORMAT);
-
- // zero index
- assertParseFailure(parser, "0" + NAME_DESC_AMY, 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, Name.MESSAGE_CONSTRAINTS); // invalid name
- assertParseFailure(parser, "1" + INVALID_PHONE_DESC, Phone.MESSAGE_CONSTRAINTS); // invalid phone
- assertParseFailure(parser, "1" + INVALID_EMAIL_DESC, Email.MESSAGE_CONSTRAINTS); // invalid email
- assertParseFailure(parser, "1" + INVALID_ADDRESS_DESC, Address.MESSAGE_CONSTRAINTS); // invalid address
- assertParseFailure(parser, "1" + INVALID_TAG_DESC, Tag.MESSAGE_CONSTRAINTS); // invalid tag
-
- // invalid phone followed by valid email
- assertParseFailure(parser, "1" + INVALID_PHONE_DESC + EMAIL_DESC_AMY, Phone.MESSAGE_CONSTRAINTS);
-
- // while parsing {@code PREFIX_TAG} alone will reset the tags of the {@code Person} being edited,
- // parsing it together with a valid tag results in error
- assertParseFailure(parser, "1" + TAG_DESC_FRIEND + TAG_DESC_HUSBAND + TAG_EMPTY, Tag.MESSAGE_CONSTRAINTS);
- assertParseFailure(parser, "1" + TAG_DESC_FRIEND + TAG_EMPTY + TAG_DESC_HUSBAND, Tag.MESSAGE_CONSTRAINTS);
- assertParseFailure(parser, "1" + TAG_EMPTY + TAG_DESC_FRIEND + TAG_DESC_HUSBAND, Tag.MESSAGE_CONSTRAINTS);
-
- // multiple invalid values, but only the first invalid value is captured
- assertParseFailure(parser, "1" + INVALID_NAME_DESC + INVALID_EMAIL_DESC + VALID_ADDRESS_AMY + VALID_PHONE_AMY,
- Name.MESSAGE_CONSTRAINTS);
- }
-
- @Test
- public void parse_allFieldsSpecified_success() {
- Index targetIndex = INDEX_SECOND_PERSON;
- String userInput = targetIndex.getOneBased() + PHONE_DESC_BOB + TAG_DESC_HUSBAND
- + EMAIL_DESC_AMY + ADDRESS_DESC_AMY + NAME_DESC_AMY + TAG_DESC_FRIEND;
-
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY)
- .withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY)
- .withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND).build();
- EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
-
- assertParseSuccess(parser, userInput, expectedCommand);
- }
-
- @Test
- public void parse_someFieldsSpecified_success() {
- Index targetIndex = INDEX_FIRST_PERSON;
- String userInput = targetIndex.getOneBased() + PHONE_DESC_BOB + EMAIL_DESC_AMY;
-
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_BOB)
- .withEmail(VALID_EMAIL_AMY).build();
- EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
-
- assertParseSuccess(parser, userInput, expectedCommand);
- }
-
- @Test
- public void parse_oneFieldSpecified_success() {
- // name
- Index targetIndex = INDEX_THIRD_PERSON;
- String userInput = targetIndex.getOneBased() + NAME_DESC_AMY;
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY).build();
- EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
- assertParseSuccess(parser, userInput, expectedCommand);
-
- // phone
- userInput = targetIndex.getOneBased() + PHONE_DESC_AMY;
- descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_AMY).build();
- expectedCommand = new EditCommand(targetIndex, descriptor);
- assertParseSuccess(parser, userInput, expectedCommand);
-
- // email
- userInput = targetIndex.getOneBased() + EMAIL_DESC_AMY;
- descriptor = new EditPersonDescriptorBuilder().withEmail(VALID_EMAIL_AMY).build();
- expectedCommand = new EditCommand(targetIndex, descriptor);
- assertParseSuccess(parser, userInput, expectedCommand);
-
- // address
- userInput = targetIndex.getOneBased() + ADDRESS_DESC_AMY;
- descriptor = new EditPersonDescriptorBuilder().withAddress(VALID_ADDRESS_AMY).build();
- expectedCommand = new EditCommand(targetIndex, descriptor);
- assertParseSuccess(parser, userInput, expectedCommand);
-
- // tags
- userInput = targetIndex.getOneBased() + TAG_DESC_FRIEND;
- descriptor = new EditPersonDescriptorBuilder().withTags(VALID_TAG_FRIEND).build();
- expectedCommand = new EditCommand(targetIndex, descriptor);
- assertParseSuccess(parser, userInput, expectedCommand);
- }
-
- @Test
- public void parse_multipleRepeatedFields_failure() {
- // More extensive testing of duplicate parameter detections is done in
- // AddCommandParserTest#parse_repeatedNonTagValue_failure()
-
- // valid followed by invalid
- Index targetIndex = INDEX_FIRST_PERSON;
- String userInput = targetIndex.getOneBased() + INVALID_PHONE_DESC + PHONE_DESC_BOB;
-
- assertParseFailure(parser, userInput, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE));
-
- // invalid followed by valid
- userInput = targetIndex.getOneBased() + PHONE_DESC_BOB + INVALID_PHONE_DESC;
-
- assertParseFailure(parser, userInput, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE));
-
- // mulltiple valid fields repeated
- userInput = targetIndex.getOneBased() + PHONE_DESC_AMY + ADDRESS_DESC_AMY + EMAIL_DESC_AMY
- + TAG_DESC_FRIEND + PHONE_DESC_AMY + ADDRESS_DESC_AMY + EMAIL_DESC_AMY + TAG_DESC_FRIEND
- + PHONE_DESC_BOB + ADDRESS_DESC_BOB + EMAIL_DESC_BOB + TAG_DESC_HUSBAND;
-
- assertParseFailure(parser, userInput,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS));
-
- // multiple invalid values
- userInput = targetIndex.getOneBased() + INVALID_PHONE_DESC + INVALID_ADDRESS_DESC + INVALID_EMAIL_DESC
- + INVALID_PHONE_DESC + INVALID_ADDRESS_DESC + INVALID_EMAIL_DESC;
-
- assertParseFailure(parser, userInput,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS));
- }
-
- @Test
- public void parse_resetTags_success() {
- Index targetIndex = INDEX_THIRD_PERSON;
- String userInput = targetIndex.getOneBased() + TAG_EMPTY;
-
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withTags().build();
- EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
-
- assertParseSuccess(parser, userInput, expectedCommand);
- }
-}
diff --git a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java
deleted file mode 100644
index d92e64d12f9..00000000000
--- a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package seedu.address.logic.parser;
-
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
-import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;
-
-import java.util.Arrays;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.logic.commands.FindCommand;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
-
-public class FindCommandParserTest {
-
- private FindCommandParser parser = new FindCommandParser();
-
- @Test
- public void parse_emptyArg_throwsParseException() {
- assertParseFailure(parser, " ", String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE));
- }
-
- @Test
- public void parse_validArgs_returnsFindCommand() {
- // no leading and trailing whitespaces
- FindCommand expectedFindCommand =
- new FindCommand(new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob")));
- assertParseSuccess(parser, "Alice Bob", expectedFindCommand);
-
- // multiple whitespaces between keywords
- assertParseSuccess(parser, " \n Alice \n \t Bob \t", expectedFindCommand);
- }
-
-}
diff --git a/src/test/java/seedu/address/model/person/PersonTest.java b/src/test/java/seedu/address/model/person/PersonTest.java
deleted file mode 100644
index 31a10d156c9..00000000000
--- a/src/test/java/seedu/address/model/person/PersonTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package seedu.address.model.person;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.BOB;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.testutil.PersonBuilder;
-
-public class PersonTest {
-
- @Test
- public void asObservableList_modifyList_throwsUnsupportedOperationException() {
- Person person = new PersonBuilder().build();
- assertThrows(UnsupportedOperationException.class, () -> person.getTags().remove(0));
- }
-
- @Test
- public void isSamePerson() {
- // same object -> returns true
- assertTrue(ALICE.isSamePerson(ALICE));
-
- // null -> returns false
- assertFalse(ALICE.isSamePerson(null));
-
- // same name, all other attributes different -> returns true
- Person editedAlice = new PersonBuilder(ALICE).withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB)
- .withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND).build();
- assertTrue(ALICE.isSamePerson(editedAlice));
-
- // different name, all other attributes same -> returns false
- editedAlice = new PersonBuilder(ALICE).withName(VALID_NAME_BOB).build();
- assertFalse(ALICE.isSamePerson(editedAlice));
-
- // name differs in case, all other attributes same -> returns false
- Person editedBob = new PersonBuilder(BOB).withName(VALID_NAME_BOB.toLowerCase()).build();
- assertFalse(BOB.isSamePerson(editedBob));
-
- // name has trailing spaces, all other attributes same -> returns false
- String nameWithTrailingSpaces = VALID_NAME_BOB + " ";
- editedBob = new PersonBuilder(BOB).withName(nameWithTrailingSpaces).build();
- assertFalse(BOB.isSamePerson(editedBob));
- }
-
- @Test
- public void equals() {
- // same values -> returns true
- Person aliceCopy = new PersonBuilder(ALICE).build();
- assertTrue(ALICE.equals(aliceCopy));
-
- // same object -> returns true
- assertTrue(ALICE.equals(ALICE));
-
- // null -> returns false
- assertFalse(ALICE.equals(null));
-
- // different type -> returns false
- assertFalse(ALICE.equals(5));
-
- // different person -> returns false
- assertFalse(ALICE.equals(BOB));
-
- // different name -> returns false
- Person editedAlice = new PersonBuilder(ALICE).withName(VALID_NAME_BOB).build();
- assertFalse(ALICE.equals(editedAlice));
-
- // different phone -> returns false
- editedAlice = new PersonBuilder(ALICE).withPhone(VALID_PHONE_BOB).build();
- assertFalse(ALICE.equals(editedAlice));
-
- // different email -> returns false
- editedAlice = new PersonBuilder(ALICE).withEmail(VALID_EMAIL_BOB).build();
- assertFalse(ALICE.equals(editedAlice));
-
- // different address -> returns false
- editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).build();
- assertFalse(ALICE.equals(editedAlice));
-
- // different tags -> returns false
- editedAlice = new PersonBuilder(ALICE).withTags(VALID_TAG_HUSBAND).build();
- assertFalse(ALICE.equals(editedAlice));
- }
-
- @Test
- public void toStringMethod() {
- String expected = Person.class.getCanonicalName() + "{name=" + ALICE.getName() + ", phone=" + ALICE.getPhone()
- + ", email=" + ALICE.getEmail() + ", address=" + ALICE.getAddress() + ", tags=" + ALICE.getTags() + "}";
- assertEquals(expected, ALICE.toString());
- }
-}
diff --git a/src/test/java/seedu/address/model/tag/TagTest.java b/src/test/java/seedu/address/model/tag/TagTest.java
deleted file mode 100644
index 64d07d79ee2..00000000000
--- a/src/test/java/seedu/address/model/tag/TagTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package seedu.address.model.tag;
-
-import static seedu.address.testutil.Assert.assertThrows;
-
-import org.junit.jupiter.api.Test;
-
-public class TagTest {
-
- @Test
- public void constructor_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> new Tag(null));
- }
-
- @Test
- public void constructor_invalidTagName_throwsIllegalArgumentException() {
- String invalidTagName = "";
- assertThrows(IllegalArgumentException.class, () -> new Tag(invalidTagName));
- }
-
- @Test
- public void isValidTagName() {
- // null tag name
- assertThrows(NullPointerException.class, () -> Tag.isValidTagName(null));
- }
-
-}
diff --git a/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java b/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java
deleted file mode 100644
index 83b11331cdb..00000000000
--- a/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package seedu.address.storage;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static seedu.address.storage.JsonAdaptedPerson.MISSING_FIELD_MESSAGE_FORMAT;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.BENSON;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Phone;
-
-public class JsonAdaptedPersonTest {
- private static final String INVALID_NAME = "R@chel";
- private static final String INVALID_PHONE = "+651234";
- private static final String INVALID_ADDRESS = " ";
- private static final String INVALID_EMAIL = "example.com";
- private static final String INVALID_TAG = "#friend";
-
- private static final String VALID_NAME = BENSON.getName().toString();
- private static final String VALID_PHONE = BENSON.getPhone().toString();
- private static final String VALID_EMAIL = BENSON.getEmail().toString();
- private static final String VALID_ADDRESS = BENSON.getAddress().toString();
- private static final List VALID_TAGS = BENSON.getTags().stream()
- .map(JsonAdaptedTag::new)
- .collect(Collectors.toList());
-
- @Test
- public void toModelType_validPersonDetails_returnsPerson() throws Exception {
- JsonAdaptedPerson person = new JsonAdaptedPerson(BENSON);
- assertEquals(BENSON, person.toModelType());
- }
-
- @Test
- public void toModelType_invalidName_throwsIllegalValueException() {
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(INVALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = Name.MESSAGE_CONSTRAINTS;
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_nullName_throwsIllegalValueException() {
- JsonAdaptedPerson person = new JsonAdaptedPerson(null, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName());
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_invalidPhone_throwsIllegalValueException() {
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = Phone.MESSAGE_CONSTRAINTS;
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_nullPhone_throwsIllegalValueException() {
- JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, null, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName());
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_invalidEmail_throwsIllegalValueException() {
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, INVALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = Email.MESSAGE_CONSTRAINTS;
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_nullEmail_throwsIllegalValueException() {
- JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, null, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Email.class.getSimpleName());
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_invalidAddress_throwsIllegalValueException() {
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, INVALID_ADDRESS, VALID_TAGS);
- String expectedMessage = Address.MESSAGE_CONSTRAINTS;
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_nullAddress_throwsIllegalValueException() {
- JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, null, VALID_TAGS);
- String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Address.class.getSimpleName());
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_invalidTags_throwsIllegalValueException() {
- List invalidTags = new ArrayList<>(VALID_TAGS);
- invalidTags.add(new JsonAdaptedTag(INVALID_TAG));
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, invalidTags);
- assertThrows(IllegalValueException.class, person::toModelType);
- }
-
-}
diff --git a/src/test/java/seedu/address/testutil/EditPersonDescriptorBuilder.java b/src/test/java/seedu/address/testutil/EditPersonDescriptorBuilder.java
deleted file mode 100644
index 4584bd5044e..00000000000
--- a/src/test/java/seedu/address/testutil/EditPersonDescriptorBuilder.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package seedu.address.testutil;
-
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-
-/**
- * A utility class to help with building EditPersonDescriptor objects.
- */
-public class EditPersonDescriptorBuilder {
-
- private EditPersonDescriptor descriptor;
-
- public EditPersonDescriptorBuilder() {
- descriptor = new EditPersonDescriptor();
- }
-
- public EditPersonDescriptorBuilder(EditPersonDescriptor descriptor) {
- this.descriptor = new EditPersonDescriptor(descriptor);
- }
-
- /**
- * Returns an {@code EditPersonDescriptor} with fields containing {@code person}'s details
- */
- public EditPersonDescriptorBuilder(Person person) {
- descriptor = new EditPersonDescriptor();
- descriptor.setName(person.getName());
- descriptor.setPhone(person.getPhone());
- descriptor.setEmail(person.getEmail());
- descriptor.setAddress(person.getAddress());
- descriptor.setTags(person.getTags());
- }
-
- /**
- * Sets the {@code Name} of the {@code EditPersonDescriptor} that we are building.
- */
- public EditPersonDescriptorBuilder withName(String name) {
- descriptor.setName(new Name(name));
- return this;
- }
-
- /**
- * Sets the {@code Phone} of the {@code EditPersonDescriptor} that we are building.
- */
- public EditPersonDescriptorBuilder withPhone(String phone) {
- descriptor.setPhone(new Phone(phone));
- return this;
- }
-
- /**
- * Sets the {@code Email} of the {@code EditPersonDescriptor} that we are building.
- */
- public EditPersonDescriptorBuilder withEmail(String email) {
- descriptor.setEmail(new Email(email));
- return this;
- }
-
- /**
- * Sets the {@code Address} of the {@code EditPersonDescriptor} that we are building.
- */
- public EditPersonDescriptorBuilder withAddress(String address) {
- descriptor.setAddress(new Address(address));
- return this;
- }
-
- /**
- * Parses the {@code tags} into a {@code Set} and set it to the {@code EditPersonDescriptor}
- * that we are building.
- */
- public EditPersonDescriptorBuilder withTags(String... tags) {
- Set tagSet = Stream.of(tags).map(Tag::new).collect(Collectors.toSet());
- descriptor.setTags(tagSet);
- return this;
- }
-
- public EditPersonDescriptor build() {
- return descriptor;
- }
-}
diff --git a/src/test/java/seedu/address/testutil/PersonUtil.java b/src/test/java/seedu/address/testutil/PersonUtil.java
deleted file mode 100644
index 90849945183..00000000000
--- a/src/test/java/seedu/address/testutil/PersonUtil.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package seedu.address.testutil;
-
-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_PHONE;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
-
-import java.util.Set;
-
-import seedu.address.logic.commands.AddCommand;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.model.person.Person;
-import seedu.address.model.tag.Tag;
-
-/**
- * A utility class for Person.
- */
-public class PersonUtil {
-
- /**
- * Returns an add command string for adding the {@code person}.
- */
- public static String getAddCommand(Person person) {
- return AddCommand.COMMAND_WORD + " " + getPersonDetails(person);
- }
-
- /**
- * Returns the part of command string for the given {@code person}'s details.
- */
- public static String getPersonDetails(Person person) {
- StringBuilder sb = new StringBuilder();
- sb.append(PREFIX_NAME + person.getName().fullName + " ");
- sb.append(PREFIX_PHONE + person.getPhone().value + " ");
- sb.append(PREFIX_EMAIL + person.getEmail().value + " ");
- sb.append(PREFIX_ADDRESS + person.getAddress().value + " ");
- person.getTags().stream().forEach(
- s -> sb.append(PREFIX_TAG + s.tagName + " ")
- );
- return sb.toString();
- }
-
- /**
- * Returns the part of command string for the given {@code EditPersonDescriptor}'s details.
- */
- public static String getEditPersonDescriptorDetails(EditPersonDescriptor 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.getEmail().ifPresent(email -> sb.append(PREFIX_EMAIL).append(email.value).append(" "));
- descriptor.getAddress().ifPresent(address -> sb.append(PREFIX_ADDRESS).append(address.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();
- }
-}
diff --git a/src/test/resources/view/UiPartTest/validFile.fxml b/src/test/resources/view/UiPartTest/validFile.fxml
index bab836af0db..caad6893a5c 100644
--- a/src/test/resources/view/UiPartTest/validFile.fxml
+++ b/src/test/resources/view/UiPartTest/validFile.fxml
@@ -1,4 +1,4 @@
-
+
Hello World!
diff --git a/src/test/resources/view/UiPartTest/validFileWithFxRoot.fxml b/src/test/resources/view/UiPartTest/validFileWithFxRoot.fxml
index 1a8b2c9e4d3..2d06dba8a66 100644
--- a/src/test/resources/view/UiPartTest/validFileWithFxRoot.fxml
+++ b/src/test/resources/view/UiPartTest/validFileWithFxRoot.fxml
@@ -1,6 +1,6 @@
-
+Hello World!