diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md
index 0f98b563e5c..dce95469068 100644
--- a/docs/DeveloperGuide.md
+++ b/docs/DeveloperGuide.md
@@ -61,7 +61,7 @@ The _Sequence Diagram_ below shows how the components interact with each other f
Each of the four main components (also shown in the diagram above),
- defines its _API_ in an `interface` with the same name as the Component.
-- implements its functionality using a concrete `{Component Name}Manager` class (which follows the corresponding API `interface` mentioned in the previous point.
+- implements its functionality using a concrete `{Component Name}Manager` class (which follows the corresponding API `interface` mentioned in the previous point).
For example, the `Logic` component defines its API in the `Logic.java` interface and implements its functionality using the `LogicManager.java` class which follows the `Logic` interface. Other components interact with a given component through its interface rather than the concrete class (reason: to prevent outside component's being coupled to the implementation of a component), as illustrated in the (partial) class diagram below.
@@ -104,9 +104,9 @@ The sequence diagram below illustrates the interactions within the `Logic` compo
How the `Logic` component works:
1. When `Logic` is called upon to execute a command, it is passed to an `AddressBookParser` object which in turn creates a parser that matches the command (e.g., `DeleteCommandParser`) and uses it to parse the command.
-1. This results in a `Command` object (more precisely, an object of one of its subclasses e.g., `DeleteCommand`) which is executed by the `LogicManager`.
-1. The command can communicate with the `Model` when it is executed (e.g. to delete a person).
-1. The result of the command execution is encapsulated as a `CommandResult` object which is returned back from `Logic`.
+2. This results in a `Command` object (more precisely, an object of one of its subclasses e.g., `DeleteCommand`) which is executed by the `LogicManager`.
+3. The command can communicate with the `Model` when it is executed (e.g. to delete a person).
+4. The result of the command execution is encapsulated as a `CommandResult` object which is returned back from `Logic`.
Here are the other classes in `Logic` (omitted from the class diagram above) that are used for parsing a user command:
@@ -158,27 +158,62 @@ Classes used by multiple components are in the `seedu.addressbook.commons` packa
This section describes some noteworthy details on how certain features are implemented.
+### Edit Contacts/Meetings feature
+
+Both the edit contact command `editc` and edit meeting command `editm` are implemented quite similarly due to the similarities between the `Person` and `Meeting` classes.
+
+This section shall therefore only go in deep detail for the implementation of the `editm` command. However, the `editc` equivalent of certain commands used by `editm` will be detailed, such that the implementation of `editc` can be fully derived.
+
+The class diagrams for both edit commands differ from the other commands in that an additional `EditMeetingDescriptor` or `EditPersonDescriptor` class is used to create the commands. The diagram for `editm` is as seen below.
+
+![EditMeetingClassDiagram](images/edit/EditMeetingClassDiagram.png)
+
+To start off, both `editc` and `editm` take in an index as their first argument, which refers to a `Person` in the displayed person list, or a `Meeting` in the displayed meeting list respectively.
+
+Next, both commands take in a variable number of optional arguments based on the arguments used by the `addc` and `addm` commands. This allows the user to input only the fields they wish to edit in the chosen `Person` or `Meeting` object, as opposed to having to type in every field.
+
+Using `editm 3 m/Friend meetup a/Mall` as an example, when input by the user, an instance of an `EditMeetingCommand` (`EditCommand` in the case of `editc` with its respective `Person` fields as arguments) is created as shown in the following Sequence Diagram.
+
+![CreateEditMeetingCommandSequenceDiagram](images/edit/CreateEditMeetingCommand-Create_EditMeetingCommand.png)
+
+As seen above, before the `EditMeetingCommandParser` creates the `EditMeetingCommand` object, it first creates an instance of an `EditMeetingDescriptor` (`EditPersonDescriptor` in the case of `editc`). This descriptor stores the new information of the fields to be edited based on the user input. From our example, it would store the `Title: Friend meetup` and `Location: Mall`.
+
+Once the instance of `EditMeetingCommand` is created, it is executed by the `LogicManager`. During execution, the current `Meeting` object referenced by the input index (3 in our example) is obtained from the meeting list returned by `getFilteredMeetingList`.
+
+Next, a new instance of `Meeting` is created using the fields from the `EditMeetingDescriptor`. Any fields not present in the descriptor us obtained from the old `Meeting` object from the previous step, as these fields do not need to be edited. From our example, the `START`, `END`, `TAG` and `ATTENDEE_LIST` will be obtained from the current `Meeting` instance as the Descriptor only contains the `TITLE` and `LOCATION` fields.
+
+Finally, the old `Meeting` object is replaced with the new instance, and the `ModelManager` is updated. These steps are denoted in the Sequence Diagram below.
+
+![EditMeetingSequenceDiagram](images/edit/EditMeetingSequenceDiagram-Execute_EditMeetingCommand.png)
+
+#### Design Considerations and Rationale
+
+1. `editm` allows the user to edit every field of `Meeting` apart from the attendee list.
+ - The commands `addmc` and `rmmc` are used to modify the attendee list of a meeting instead.
+ - This retains the identity of the edit commands as commands that modify field information, as opposed to `addmc` and `rmmc` which can be seen as commands that link multiple objects together.
+
### View Contacts/Meetings feature
#### Implementation
-Both the view contact command `viewc` and the view meeting command `viewm` are implemented in the exact same way due to the similarities between the `Person` and `Meeting` classes.
+Just like the Edit commands, the view contact command `viewc` and the view meeting command `viewm` are implemented in the exact same way due to the similarities between the `Person` and `Meeting` classes.
-As such, this section shall only detail the implementation of the `viewc` command. However the implementation of `viewm` can be derived by replacing some `Person` related functions/classes/objects with its `Meeting` counterpart.
+As such, this section shall only detail the implementation of the `viewc` command. However, the implementation of `viewm` can be derived by replacing some `Person` related functions/classes/objects with its `Meeting` counterpart.
-`viewc` and `viewm` both take in an index as their only argument. This refers to the `Person` or `Meeting` index respectively as displayed on either the Contact list or Meeting list.
+`viewc` and `viewm` both take in an index as their only argument, which refers to a `Person` in the displayed person list, or a `Meeting` in the displayed meeting list respectively.
-When `viewc 2` is used, an instance of a `ViewContactCommand` (`ViewMeetingCommand` in the case of `viewm`) is created as shown in the following Sequence Diagram. This step does not differ from the way other commands have been shown to be created. The argument for our example would just be `2`, which would be stored as the `targetIndex` field of the `ViewContactCommand` object.
+Using `viewc 2` as an example, when input by the user, an instance of a `ViewContactCommand` (`ViewMeetingCommand` in the case of `viewm`) is created as shown in the following Sequence Diagram. This step does not differ from the way other commands have been shown to be created. The argument for our example would just be `2`, which would be stored as the `targetIndex` field of the `ViewContactCommand` object.
-![ViewContactCommandSequenceDiagram](images/tracing/ViewContactCommandSequenceDiagram-ViewContactCommandSequence.png)
+![CreateViewContactCommandSequenceDiagram](images/view/CreateViewContactCommand-Create_ViewContactCommand.png)
-Once the instance of `ViewContactCommand` is created, it is executed. During execution, the command stores the contents of its `targetIndex` field in the `ModelManager` using its `setViewedPersonIndex` method as shown in the next Sequence Diagram. For `ViewMeetingCommand` it would use the `setViewedMeetingIndex` method instead.
+Once the instance of `ViewContactCommand` is created, it is executed by the `LogicManager`. During execution, the command stores the contents of its `targetIndex` field in the `ModelManager` using its `setViewedPersonIndex` method as shown in the next Sequence Diagram. For `ViewMeetingCommand` it would use the `setViewedMeetingIndex` method instead.
-![StoreViewedItemsToModelDiagram](images/tracing/ViewCommandsSequenceDiagram-StoreViewedItemsToModel.png)
+![StoreViewedItemsToModelDiagram](images/view/ViewCommandsSequenceDiagram-StoreViewedItemsToModel.png)
Once the indexes of the `Person` and `Meeting` objects to view (if any) are stored in `ModelManager`, their corresponding `Person` and `Meeting` objects (in this case the 2nd `Person` as displayed on the list) are obtained by the `MainWindow` as a `Pair` through the `getViewedItems` method of the `LogicManager` class. As such, both objects can then be forwarded to the `InfoDisplayPanel` using `setViewedModel`, which then displays detailed information of both objects. This process is denoted in the final Sequence Diagram below.
-![ForwardViewedPersonMeetingtoUiDiagram](images/tracing/UiViewItemsSequenceDiagram-ForwardViewedPerson&MeetingToUi.png)
+![ForwardViewedPersonMeetingtoUiDiagram](images/view/UiViewItemsSequenceDiagram-ForwardViewedPerson&MeetingToUi.png)
+
#### Design Considerations and Rationale
1. Passing viewed `Person` and `Meeting` from Model to Ui through Logic:
@@ -195,7 +230,6 @@ Once the indexes of the `Person` and `Meeting` objects to view (if any) are stor
- For the case of `editc` and `editm`, this is judged to not be an issue as the view commands still obey their definition of displaying the item at a specified list index.
- For the case of `deletec`, `deletem`, `findc` and `findm`, a simple fix is to simply set the stored `Index` to null only for these commands.
-
### Find meeting feature
#### Behaviour and Implementation
@@ -224,7 +258,6 @@ Step 2. The `FindMeetingCommand` will be immediately executed and will call `set
The following diagrams show the entire sequence flow for `LogicManager#execute()` for FindMeetingCommand.
![FindMeetingSequence2](images/FindMeetingSequence2.png)
-
#### Design Considerations and Rationale
1. Given the amount of predicates `FindMeetingCommand` is supposed to use, every predicate needs to be combined in order to maintain good SLAP.
@@ -253,8 +286,8 @@ The following sequence diagram shows how the add attendee operation works:
A Person object can be obtained from a Meeting's list of attendees by searching through `UniquePersonList`
for a `Person` with a name matching `attendeeName`.
-
### Remove attendee feature
+
User can specify an Attendee to remove from a specified Meeting by specifying its index in the list of Attendees.
This is the main motivation behind using a LinkedHashSet for the implementation of the Attendee Set.
@@ -262,7 +295,6 @@ The following sequence diagram shows how the remove attendee operation works:
![RemoveAttendeeSequenceDiagram](images/RemoveAttendeeSequenceDiagram.png)
-
### \[Proposed\] Undo/redo feature
#### Proposed Implementation
@@ -346,31 +378,31 @@ _{more aspects and alternatives to be added}_
### Keeping track of last meeting with contact
-Keeping track of the user's last meeting with their contact is facilitated by the addition of a `LastContactedTime` object to `Person`.
-Thus, each instance of `Person` will contain an immutable `LastContactedTime` object that stores the user's last meeting with that contact.
+Keeping track of the user's last meeting with their contact is facilitated by the addition of a `LastContactedTime` object to `Person`.
+Thus, each instance of `Person` will contain an immutable `LastContactedTime` object that stores the user's last meeting with that contact.
The following steps shows how `LastContactedTime` is implemented and utilized in the application.
Step 1. The user inputs the `addc` command into the `CommandBox` input field, with the added field `l/[LAST_CONTACTED_TIME]`.
-The following diagram summarizes steps 2 to 6:
+The following diagram summarizes steps 2 to 6:
-Step 2. Entering a correct command with the `Enter` key then calls `execute` on `LogicManager`.
-Step 3. `LogicManager` then calls `AddressBookParser#parseCommand(commandText)` on the `commandText` String, which recognizes that it is an `addc` command.
-Step 4. `AddressBookParser` then calls `AddCommandParser#parse()` on the command arguments.
-Step 5. `AddCommandParser` then calls `ParserUtil#parseContactTime()` which parses the last contacted time and returns a `LocalDateTime` object called `lastContactedTime`.
+Step 2. Entering a correct command with the `Enter` key then calls `execute` on `LogicManager`.
+Step 3. `LogicManager` then calls `AddressBookParser#parseCommand(commandText)` on the `commandText` String, which recognizes that it is an `addc` command.
+Step 4. `AddressBookParser` then calls `AddCommandParser#parse()` on the command arguments.
+Step 5. `AddCommandParser` then calls `ParserUtil#parseContactTime()` which parses the last contacted time and returns a `LocalDateTime` object called `lastContactedTime`.
Step 6. The `lastContactedTime` object is then passed to the `Person` constructor, which creates a new `Person` that calls the `LastContactedTime` constructor with it.
The following diagram summarizes steps 7 and 8:
-Step 7. The completed `Person` is passed to an `AddCommand` constructor which return a new `AddCommand` that can be executed.
-Step 8. `LogicManager` then executes the `AddCommand` on the application model.
-Step 9. Futher execution is carried out, which like before adds the `Person` object to the list of `Person`s in the `Model`, and updates the `Storage` with this new `Person`.
+Step 7. The completed `Person` is passed to an `AddCommand` constructor which return a new `AddCommand` that can be executed.
+Step 8. `LogicManager` then executes the `AddCommand` on the application model.
+Step 9. Further execution is carried out, which like before adds the `Person` object to the list of `Person`s in the `Model`, and updates the `Storage` with this new `Person`.
#### Design Consideration: Updating last meeting with contact
-Solution:
+Solution:
This is facilitated by the addition of the `MarkDoneCommand`. When a meeting is marked as done, the attendees of the meeting will be updated with their LastContactedTime field updated to the end time of the meeting.
---
@@ -402,7 +434,7 @@ This is facilitated by the addition of the `MarkDoneCommand`. When a meeting is
Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*`
-| Priority | As a … | I want to … | So that I can… |
+| Priority | As a … | I want to … | So that I can… |
| -------- | ----------------------------------------- | ------------------------------- | ------------------------------------- |
| `[EPIC]` | agent who has meetings | have a meeting schedule | keep track of them |
| `* * *` | agent | create new meetings | |
@@ -424,6 +456,7 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
| `* * *` | agent | add contacts to meetings | |
| `* * *` | agent | remove contacts from meetings | |
| `* * *` | agent | view contacts in meetings | |
+| `* *` | agent | mark meetings as complete | know which meetings are still pending |
| `*` | agent who wants to meet clients regularly | know the last contacted date | when to touch base with a client |
_{More to be added}_
@@ -479,10 +512,10 @@ _{More to be added}_
2. OutBook shows a list of meetings.
3. User requests to view details of a specific meeting.
4. OutBook shows the details of the meeting.
-4. User requests to remove a specific contact from the meeting.
-5. OutBook removes the contact from the meeting.
5. User requests to remove a specific contact from the meeting.
6. OutBook removes the contact from the meeting.
+7. User requests to remove a specific contact from the meeting.
+8. OutBook removes the contact from the meeting.
Use case ends.
@@ -593,16 +626,16 @@ testers are expected to do more *exploratory* testing.
1. Download the jar file and copy into an empty folder
- 1. Double-click the jar file Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
+ 2. Double-click the jar file Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
-1. Saving window preferences
+2. Saving window preferences
1. Resize the window to an optimum size. Move the window to a different location. Close the window.
- 1. Re-launch the app by double-clicking the jar file.
+ 2. Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
-1. _{ more test cases … }_
+3. _{ more test cases … }_
### Deleting a person
@@ -610,16 +643,16 @@ testers are expected to do more *exploratory* testing.
1. Prerequisites: List all persons using the `list` command. Multiple persons in the list.
- 1. Test case: `delete 1`
+ 2. 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 … }_
+2. _{ more test cases … }_
### Saving data
@@ -627,4 +660,4 @@ testers are expected to do more *exploratory* testing.
1. _{explain how to simulate a missing/corrupted file, and the expected behavior}_
-1. _{ more test cases … }_
+2. _{ more test cases … }_
diff --git a/docs/UserGuide.md b/docs/UserGuide.md
index 80957f00dcc..0868f42a758 100644
--- a/docs/UserGuide.md
+++ b/docs/UserGuide.md
@@ -3,22 +3,21 @@ layout: page
title: OutBook User Guide
---
-OutBook is an app that allows freelance insurance agents to manage their numerous contacts and meeting schedule. It is optimised for Command Line Interface (CLI) aims to significantly reduce the time needed for organizational tasks.
+OutBook is an app that allows freelance insurance agents to manage their numerous contacts and meeting schedule. It is optimised for Command Line Interface (CLI) and aims to significantly reduce the time needed for organizational tasks.
-This guide is to help you explore and learn about what are its features and how to use them.
-Outbook has 2 lists which are used to track contacts and meetings respectively. These list can be filtered to show the specific data you need.
+This guide is to help you explore and learn about what are its features and how to use them.
+Outbook has 2 lists which are used to track contacts and meetings respectively. These list can be filtered to show the specific data you need.
It is able to add, edit and delete any contacts and meetings you want. As well as add custom remarks and tags for your specific needs.
-
-
# Table of Content
-* Table of Contents
-{:toc}
+- Table of Contents
+ {:toc}
+
+---
---------------------------------------------------------------------------------------------------------------------
# Quick start
@@ -36,20 +35,21 @@ It is able to add, edit and delete any contacts and meetings you want. As well a
5. 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.
Some example commands you can try:
- * `listc` : Lists all contacts.
+ - `listc` : Lists all contacts.
- * `addc n/John Doe p/98765432 e/johnd@example.com l/10.10.2023 1000 o/NUS` : Adds a contact named `John Doe` to OutBook.
+ - `addc n/John Doe p/98765432 e/johnd@example.com lc/10.10.2023 1000 o/NUS` : Adds a contact named `John Doe` to OutBook.
- * `deletec 3` : Deletes the 3rd contact shown in the contact list.
+ - `deletec 3` : Deletes the 3rd contact shown in the contact list.
- * `deletem 1` : Deletes the 1st meeting shown in the meeting list.
+ - `deletem 1` : Deletes the 1st meeting shown in the meeting list.
- * `clear` : Deletes all contacts and meetings.
+ - `clear` : Deletes all contacts and meetings.
+
+ - `exit` : Exits the app.
- * `exit` : Exits the app.
6. Refer to the [Features](#features) below for details of each command.
---------------------------------------------------------------------------------------------------------------------
+---
@@ -60,21 +60,21 @@ It is able to add, edit and delete any contacts and meetings you want. As well a
**:information_source: Notes about the command format:**
* 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`.
+ e.g. in `addc n/NAME`, `NAME` is a parameter which can be used as `addc n/John Doe`.
-* Items in square brackets are optional.
+- 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`.
-* Items with `…` after them can be used multiple times including zero times.
+- 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.
-* You can place parameters in any order.
+- You can place parameters in any order.
e.g. if the command specifies `n/NAME p/PHONE_NUMBER`, `p/PHONE_NUMBER n/NAME` is also acceptable.
-* Any extraneous parameters you place for commands that do not take in parameters (such as `help`, `list`, `exit` and `clear`) will be ignored.
+* Any extraneous parameters you place for commands that do not take in parameters (such as `help`, `listc`, `exit` and `clear`) will be ignored.
e.g. if you type `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.
+- 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`
@@ -93,82 +93,77 @@ Format: `help`
Adds a contact to OutBook.
-<<<<<<< HEAD
-Format: `addc n/NAME p/PHONE_NUMBER e/EMAIL l/LAST_CONTACTED_TIME s/STATUS [r/REMARK][t/TAG]…`
-=======
Format: `addc n/NAME p/PHONE_NUMBER e/EMAIL lc/LAST_CONTACTED_TIME [s/STATUS] [r/REMARK] [t/TAG]…`
->>>>>>> master
-
-* NAME, PHONE_NUMBER, EMAIL and LAST_CONTACTED_TIME are compulsory fields. STATUS, REMARK and TAG are optional.
-* PHONE_NUMBER must contain only numbers, and be at least 3 digits long.
-* EMAIL must be of the format local-part@domain and adhere to the following constraints:
- 1. The local-part should only contain alphanumeric characters and these special characters, excluding the parentheses, (+_.-).
+* `NAME`, `PHONE_NUMBER`, `EMAIL` and `LAST_CONTACTED_TIME` are compulsory fields. `STATUS`, `REMARK` and `TAG` are optional.
+* `PHONE_NUMBER` must contain only numbers, and be at least 3 digits long.
+* `EMAIL` must be of the format local-part@domain and adhere to the following constraints:
+ 1. The local-part should only contain alphanumeric characters and the following special characters `+ _ . -`.
2. The local-part may not start or end with any special characters.
3. The domain name is made up of domain labels separated by periods.
The domain name must:
- - end with a domain label at least 2 characters long
- - have each domain label start and end with alphanumeric characters
- - have each domain label consist of alphanumeric characters, separated only by hyphen
+ - end with a domain label at least 2 characters long
+ - have each domain label start and end with alphanumeric characters
+ - have each domain label consist of alphanumeric characters, separated only by hyphen
-* LAST_CONTACTED_TIME must contain both date and time and adhere to the dd.MM.yyyy HHmm format.
- - For instance, 1st October 2023, 10:00am will be written as 01.10.2023 1000.
-* STATUS, if included, must be one of { NIL, Prospective, Active, Inactive, Claimant, Renewal } or blank.
+* `LAST_CONTACTED_TIME` must contain both date and time and adhere to the `DD.MM.YYYY HHMM` format.
+ - eg. 1st October 2023, 10:00am will be written as `01.10.2023 1000`.
+* STATUS, if included, must be one of `NIL, Prospective, Active, Inactive, Claimant, Renewal` or blank.
:bulb: **Tip:**
You can put any number of tags (including 0) on a contact.
### Listing all persons : `listc`
-<<<<<<< HEAD
-Shows you a list of all contacts in OutBook.
-=======
Shows a list of all contacts in OutBook. Contacts are sorted by LAST_CONTACTED_TIME by default.
->>>>>>> master
Format: `listc`
-
### Deleting a person : `deletec`
Deletes a contact from OutBook.
Format: `deletec INDEX`
-* Deletes the contact 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, …
+- Deletes the contact 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, …
Examples:
-* `listc` followed by `delete 2` deletes the 2nd person in the results of the `listc` command.
-* `findc Betsy` followed by `delete 1` deletes the 1st person in the results of the `findc` command.
+- `listc` followed by `delete 2` deletes the 2nd person in the results of the `listc` command.
+- `findc Betsy` followed by `delete 1` deletes the 1st person in the results of the `findc` command.
### Editing a contact : `editc`
Edits an existing contact in OutBook.
-Format: `editc INDEX [n/NAME] [p/PHONE] [e/EMAIL] [lc/LAST_CONTACTED_TIME] [s/STATUS] [s/REMARK] [t/TAG]…`
+Format: `editc INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [lc/LAST_CONTACTED_TIME] [s/STATUS] [r/REMARK] [t/TAG]…`
-* Edits the contact 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, …
-* All fields are optional, but at least one 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.
+- Edits the contact 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, …
+- All fields are optional, but at least one 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.
Examples:
* `editc 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.
* `editc 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags.
+
+
+- `editc 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.
+- `editc 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags.
+
### Viewing detailed contact information : `viewc`
Views detailed information of a contact in OutBook.
@@ -180,72 +175,42 @@ Format: `viewc INDEX`
* The index **must be a positive integer** 1, 2, 3, …
* Displays contact Name, Phone, Email, Last Contacted Time, Status, Remarks and Tags.
* The displayed contact is reset when the `deletec` and `findc` commands are used.
+* The displayed contact may change when `editc` is used in a way that modifies the order of the displayed person list, such as by editing the `LAST_CONTACTED_DATE`. This is intentional as the `editc` command is meant to display information based on the contact list index.
Examples:
* `viewc 2` Displays detailed information related to the 2nd contact on the list.
-
-
-
-### Editing a contact : `editc`
-
-Edits an existing contact in OutBook.
-
-Format: `editc INDEX [n/NAME] [p/PHONE] [e/EMAIL] [l/LAST_CONTACTED_TIME] [s/STATUS] [r/REMARK] [t/TAG]…`
-
-* Edits the contact 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, …
-* All fields are optional, but at least one 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.
-
-Examples:
-* `editc 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.
-* `editc 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags.
-
-
-### Remarking a contact : `remark`
-
-Adds a remark to a contact.
-
-Format: `remark INDEX r/REMARK`
-
-* Adds a remark to the contact specified with `INDEX`. The index refers to the index number shown in the displayed person list. The index**must be a positive integer** 1, 2, 3, …
-* Existing remark will be replaced with `REMARK`.
-* You can remove an existing remark by typing `r/`.
-
-*Examples:
-* `remark 1 r/Owes me a favour` Replaces the previous remark for the 1st contact with "Owes me a favour".
-
+
### Search for persons using contact fields: `findc`
-Find persons whose contact details match the keywords specified for at least 1 of these fields: name, phone, email, status, tag
+Find persons whose contact details match the keywords specified for at least 1 of these fields: `NAME`, `PHONE_NUMBER`, `EMAIL`, `STATUS`, `TAG`.
Format: `findc [n/KEYWORDS] [p/KEYWORDS] [e/KEYWORDS] [lc/DATETIME] [s/KEYWORDS] [t/KEYWORDS]`
-* The search is case-insensitive. e.g `shop` will match `SHOP`
-* The order of the keywords does not matter. e.g. `Shop Meet` will match `Meet Shop`
-* For name, status and tags, only full words will be matched e.g. `Meet` will not match `Meeting`
-* For email, any characters (alphanumeric, special characters) will be matched e.g. `_` will match `m_e@gmail.com`
-* For phone, the entire length of the input digits will be matched e.g. `913` will match `90091300` but not `90103000`
-* For last contacted time, the input must adhere to the dd.MM.yyyy HHmm format e.g. 9th October 2023 10.30am will be `09.10.2023 1030`
-* For a single field, a Person must match at least one keyword to be returned as a result (i.e. `OR` search).
- e.g. `John Doe` will return `John Lee`, `James Doe`
-* If there are multiple fields specified, the Person must match at least one keyword in each field to be returned as a result (i.e. `AND` search).
- e.g. `n/John Doe s/Active` will return `Name: John Lee, Status: Active`
+* The search is case-insensitive. e.g `shop` will match `SHOP`.
+* The order of the keywords does not matter. e.g. `Shop Meet` will match `Meet Shop`.
+* For `NAME`, `STATUS` and `TAG`, only full words will be matched e.g. `Meet` will not match `Meeting`.
+* For `EMAIL`, any characters (alphanumeric, special characters) will be matched e.g. `_` will match `m_e@gmail.com`.
+* For `PHONE_NUMBER`, the entire length of the input digits will be matched e.g. `913` will match `90091300` but not `90103000`.
+* For `LAST_CONTACTED_TIME`, the input must adhere to the `DD.MM.YYYY HHMM` format.
+ - e.g. 9th October 2023, 10.30am will be written as `09.10.2023 1030`.
+* If only one field is provided, all Persons matching at least one keyword will be returned (i.e. `OR` search).
+ - e.g. `John Doe` will return `John Lee`, `James Doe`.
+* If multiple fields are provided, only Persons matching at least one keyword in each field will be returned (i.e. `AND` search).
+ - e.g. `n/John Doe s/active` will return `Name: John Lee, Status: Active` but not `Name: James Doe, Status: Claimant`.
Examples:
-* `findc n/alice` returns `Alice` and `alice tan`
-* `findc p/51` returns `95163890` and `40351`
-* `findc e/_@GMAIL` returns `alice_@gmail.com`
-* `findc p/9 s/inactive claimant t/friend` returns persons with a `9` in their phone number, whose status is either `inactive` or `claimant`, and has a `friend` tag
- ![result for 'findContact'](images/findContactResult.png)
+- `findc n/alice` returns `Alice` and `alice tan`
+- `findc p/51` returns `95163890` and `40351`
+- `findc e/_@GMAIL` returns `alice_@gmail.com`
+- `findc p/9 s/inactive claimant t/friend` returns persons with a `9` in their phone number, whose status is either `inactive` or `claimant`, and has a `friend` tag
+ ![result for 'findContact'](images/findContactResult.png)
+
## Meeting commands
### Adding a meeting: `addm`
@@ -255,12 +220,13 @@ Meetings are sorted by start time given.
Format: `addm m/TITLE a/LOCATION s/START e/END [t/TAG]…`
-* START and END must contain both date and time and adhere to the dd.MM.yyyy HHmm format.
- - For instance, 1st October 2023, 10:00am will be written as 01.10.2023 1000.
+* `START` and `END` must contain both date and time and adhere to the `DD.MM.YYYY HHMM` format.
+ - eg. 1st October 2023, 10:00am will be written as `01.10.2023 1000`.
Examples:
-* `addm m/Lunch a/Cafeteria s/20.09.2023 1200 e/20.09.2023 1300`
-* `addm m/CS2103T meeting a/Zoom call url s/20.09.2023 1000 e/20.09.2023 1200`
+
+- `addm m/Lunch a/Cafeteria s/20.09.2023 1200 e/20.09.2023 1300`
+- `addm m/CS2103T meeting a/Zoom call url s/20.09.2023 1000 e/20.09.2023 1200`
### Listing all meetings : `listm`
@@ -268,21 +234,20 @@ Shows a list of all meetings in OutBook. Meetings are sorted by START by default
Format: `listm`
-
### Deleting a meeting : `deletem`
Deletes a meeting from OutBook.
Format: `deletem INDEX`
-* Deletes the meeting at the specified `INDEX`.
-* The index refers to the index number shown in the displayed meeting list.
-* The index **must be a positive integer** 1, 2, 3, …
+- Deletes the meeting at the specified `INDEX`.
+- The index refers to the index number shown in the displayed meeting list.
+- The index **must be a positive integer** 1, 2, 3, …
Examples:
-* `listm` followed by `deletem 2` deletes the 2nd meeting in the results of the `listm` command.
-* `findm m/Project` followed by `deletem 1` deletes the 1st meeting in the results of the `findm` command.
+- `listm` followed by `deletem 2` deletes the 2nd meeting in the results of the `listm` command.
+- `findm m/Project` followed by `deletem 1` deletes the 1st meeting in the results of the `findm` command.
### Editing a meeting : `editm`
@@ -290,17 +255,17 @@ Edits an existing meeting in OutBook.
Format: `editm INDEX [m/TITLE] [a/LOCATION] [s/START] [e/END] [t/TAG]…`
-* Edits the meeting at the specified `INDEX`. The index refers to the index number shown in the displayed meeting 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 meeting will be removed i.e adding of tags is not cumulative.
-* You can remove all the meeting’s tags by typing `t/` without
+- Edits the meeting at the specified `INDEX`. The index refers to the index number shown in the displayed meeting 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 meeting will be removed i.e adding of tags is not cumulative.
+- You can remove all the meeting’s tags by typing `t/` without
specifying any tags after it.
Examples:
-* `editm 1 a/Hawker Centre s/15.09.2023 1500` Edits the location and start of the 1st meeting to be `Hawker Centre` and `15.09.2023 1500` respectively.
-* `editm 2 m/Zoom meeting t/` Edits the title of the 2nd meeting to be `Zoom meeting` and clears all existing tags.
+- `editm 1 a/Hawker Centre s/15.09.2023 1500` Edits the location and start of the 1st meeting to be `Hawker Centre` and `15.09.2023 1500` respectively.
+- `editm 2 m/Zoom meeting t/` Edits the title of the 2nd meeting to be `Zoom meeting` and clears all existing tags.
### Viewing detailed meeting information : `viewm`
@@ -313,33 +278,36 @@ Format: `viewm INDEX`
* The index **must be a positive integer** 1, 2, 3, …
* Displays meeting Title, Location, Start/End, Attendees and Tags.
* The displayed meeting is reset when the `deletem` and `findm` commands are used.
+* The displayed meeting may change when `editm` is used in a way that modifies the order of the displayed meeting list, such as by editing the `START`. This is intentional as the `editm` command is meant to display information based on the meeting list index.
Examples:
* `viewm 2` Displays detailed information related to the 2nd meeting on the list, including current attendees.
+
+
### Search for Meetings using meeting fields: `findm`
-Find meetings which details match the keywords you specified for at least 1 of these fields: title, location, attendee, tag; and fall within the start and end time you give.
+Find meetings with details matching the keywords you specified for at least 1 of these fields: `TITLE`, `LOCATION`, `ATTENDEE_NAME`, `TAG`; and falls within the `START` and `END` time you give.
-Format: `findm [m/KEYWORDS] [a/KEYWORDS] [t/KEYWORDS] [n/ATTENDEENAME] [s/START e/END]`
+Format: `findm [m/KEYWORDS] [a/KEYWORDS] [t/KEYWORDS] [n/ATTENDEE_NAME] [s/START e/END]`
-* The search is case-insensitive. e.g `shop` will match `SHOP`
-* The order of the keywords does not matter. e.g. `Shop Meet` will match `Meet Shop`
-* Title, location, tags and attendees are searched, within the time frame given by START and END
-* Only full words will be matched e.g. `Meet` will not match `Meeting`
-* For a single field, a Meeting must match at least one keyword will be returned (i.e. `OR` search).
- e.g. `Shop Meet` will return `Meeting: Shop at mall`, `Meeting: Meet client`
-* If there are multiple fields the meeting must match at least one keyword for each field to be returned (i.e. `AND` search).
- e.g. `m/Shop Meet a/Mall` will return `Meeting: Shop at mall, Location:Mall`
+* The search is case-insensitive. e.g `shop` will match `SHOP`.
+* The order of the keywords does not matter. e.g. `Shop Meet` will match `Meet Shop`.
+* `TITLE`, `LOCATION`, `TAG` and `ATTENDEE_NAME` are searched, within the time frame given by `START` and `END`.
+* Only full words will be matched e.g. `Meet` will not match `Meeting`.
+* If only one field is provided, all Meetings matching at least one keyword will be returned (i.e. `OR` search).
+ e.g. `m/Shop Meet` will return `Meeting: Shop at mall`, `Meeting: Meet client`.
+* If multiple fields are provided, only Meetings matching at least one keyword in each field will be returned (i.e. `AND` search).
+ e.g. `m/Shop Meet a/Mall` will return `Meeting: Shop at mall, Location: Mall` but not `Meeting: Meet client, Location: Park`.
Examples:
* `findm m/project` returns `project` and `Project work`
* `findm m/zoom meeting` returns `Zoom session`, `Zoom meeting`, `Meeting advisor`
* `findm s/09.09.2023 0000 e/09.10.2023 0000` returns all meetings between 09.09.2023 0000 and 09.10.2023 0000
* `findm m/Meeting s/09.09.2023 0000 e/09.10.2023 0000` returns `Zoom meeting`, `Meeting advisor`, if these meetings start after 09.09.2023 0000 and end before 09.10.2023 0000
-
+
![result for 'findAlexMeeting'](images/findAlexMeetingResult.png)
@@ -352,7 +320,7 @@ Adds a contact to a meeting as an attendee.
Format: `addmc MEETING_INDEX CONTACT_INDEX`
-* Adds the contact you specified with `CONTACT_INDEX` to a meeting specified with `MEETING_INDEX`.
+* Adds the contact you specified with `CONTACT_INDEX` to a meeting specified with `MEETING_INDEX`.
* `MEETING_INDEX` refers to the index number shown in the displayed meeting list.
* `CONTACT_INDEX` refers to the index number shown in the displayed contact list.
* The indexes **must be positive integers** 1, 2, 3, …
@@ -360,7 +328,8 @@ Format: `addmc MEETING_INDEX CONTACT_INDEX`
* Contact name will be listed in the detailed description of meetings when `viewm` is used.
Examples:
-* `addmc 3 1` adds the 1st contact as an attendee to the 3rd meeting in OutBook.
+
+- `addmc 3 1` adds the 1st contact as an attendee to the 3rd meeting in OutBook.
### Remove contact from meeting: `rmmc`
@@ -368,16 +337,29 @@ Removes a contact from a meeting.
Format: `rmmc MEETING_INDEX ATTENDEE_INDEX`
-* Removes a contact at the specified `ATTENDEE_INDEX` to the meeting at the specified `MEETING_INDEX`.
-* `MEETING_INDEX` refers to the index number shown in the displayed meeting list.
-* `ATTENDEE_INDEX` refers to the index number of the attendee as shown in `viewm`.
-* The indexes **must be positive integers** 1, 2, 3, …
-* Both `MEETING_INDEX` & `ATTENDEE_INDEX` must refer to the index of an existing meeting or attendee.
+- Removes a contact at the specified `ATTENDEE_INDEX` to the meeting at the specified `MEETING_INDEX`.
+- `MEETING_INDEX` refers to the index number shown in the displayed meeting list.
+- `ATTENDEE_INDEX` refers to the index number of the attendee as shown in `viewm`.
+- The indexes **must be positive integers** 1, 2, 3, …
+- Both `MEETING_INDEX` & `ATTENDEE_INDEX` must refer to the index of an existing meeting or attendee.
Examples:
-* `rmmc 3 2` removes the 2nd attendee from the 3rd meeting in OutBook.
-
+- `rmmc 3 2` removes the 2nd attendee from the 3rd meeting in OutBook.
+
+### Marking a meeting as complete : `mark`
+
+Marks a meeting in OutBook as complete. All attendees of the meeting will have their LC (last contacted) field updated to the end time of the meeting.
+
+Format: `mark INDEX`
+
+- Marks the meeting at the specified `INDEX` as complete.
+- The index refers to the index number shown in the displayed meeting list.
+- The index **must be a positive integer** 1, 2, 3, …
+
+Examples:
+
+- `listm` followed by `mark 2` marks the 2nd meeting in the results of the `listm` command.
### Clearing all entries : `clear`
@@ -403,8 +385,8 @@ OutBook data are saved automatically as a JSON file `[JAR file location]/data/ou
If your changes to the data file makes its format invalid, OutBook 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.
+---
---------------------------------------------------------------------------------------------------------------------
## FAQ
@@ -412,33 +394,34 @@ If your changes to the data file makes its format invalid, OutBook will discard
**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 OutBook home folder.
---------------------------------------------------------------------------------------------------------------------
+---
## 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.
---------------------------------------------------------------------------------------------------------------------
+---
+
## Command summary
-| Action | Format, Examples |
-|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| **Add contact** | `addc n/NAME p/PHONE_NUMBER e/EMAIL l/LAST_CONTACTED_TIME o/ORGANISATION [r/REMARK] [t/TAG]…` e.g., `add n/James Ho p/22224444 e/jamesho@example.com l/09.09.2023 0000 o/NUS t/friend t/colleague` |
-| **Add contact to meeting** | `addmc MEETING_INDEX CONTACT_INDEX` e.g., `addmc 2 1` |
-| **Add meeting** | `addm m/TITLE a/LOCATION s/START e/END [t/TAG]…` e.g., `addm m/Lunch a/Cafeteria s/20.09.2023 1200 e/20.09.2023 1300` |
-| **Clear** | `clear` |
-| **Delete contact** | `deletec INDEX` e.g., `deletec 3` |
-| **Delete meeting** | `deletem INDEX` e.g., `deletem 3` |
-| **Edit contact** | `editc INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [l/LAST_CONTACTED_TIME] [o/ORGANISATION] [r/REMARK] [t/TAG]…` e.g.,`editc 2 n/James Lee e/jameslee@example.com` |
-| **Edit meeting** | `editm INDEX [m/TITLE] [a/LOCATION] [s/START] [e/END] [t/TAG]…` e.g.,`editm 1 a/Hawker Centre s/15.09.2023 1500` |
-| **Find contact** | `findc KEYWORD [MORE_KEYWORDS]` e.g., `findc James Jake` |
-| **Find meeting** | `findm [m/KEYWORDS] [a/KEYWORDS] [t/KEYWORDS] [n/ATTENDEENAME] [s/START e/END]` e.g., `findm m/Zoom Meet s/09.09.2023 0000 e/09.10.2023 0000` |
-| **Help** | `help` |
-| **List contacts** | `listc` |
-| **List meetings** | `listm` |
-| **Remove contact from meeting** | `rmmc MEETING_INDEX ATTENDEE_INDEX` e.g., `rmmc 2 2` |
-| **View contact details** | `viewc INDEX` e.g., `viewc 4` |
-| **View meeting details** | `viewm INDEX` e.g., `viewm 4` |
-| **Exit** | `exit` |
+| Action | Format, Examples |
+|---------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| **Add contact** | `addc n/NAME p/PHONE_NUMBER e/EMAIL lc/LAST_CONTACTED_TIME [r/REMARK] [t/TAG]…` e.g., `add n/James Ho p/22224444 e/jamesho@example.com lc/09.09.2023 0000 o/NUS t/friend t/colleague` |
+| **Add contact to meeting** | `addmc MEETING_INDEX CONTACT_INDEX` e.g., `addmc 2 1` |
+| **Add meeting** | `addm m/TITLE a/LOCATION s/START e/END [t/TAG]…` e.g., `addm m/Lunch a/Cafeteria s/20.09.2023 1200 e/20.09.2023 1300` |
+| **Clear** | `clear` |
+| **Delete contact** | `deletec INDEX` e.g., `deletec 3` |
+| **Delete meeting** | `deletem INDEX` e.g., `deletem 3` |
+| **Edit contact** | `editc INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [lc/LAST_CONTACTED_TIME] [r/REMARK] [t/TAG]…` e.g.,`editc 2 n/James Lee e/jameslee@example.com` |
+| **Edit meeting** | `editm INDEX [m/TITLE] [a/LOCATION] [s/START] [e/END] [t/TAG]…` e.g.,`editm 1 a/Hawker Centre s/15.09.2023 1500` |
+| **Find contact** | `findc [n/KEYWORDS] [p/KEYWORDS] [e/KEYWORDS] [lc/LAST_CONTACTED_TIME] [s/KEYWORDS] [t/KEYWORDS]` e.g., `findc n/James Jake s/active claimant` |
+| **Find meeting** | `findm [m/KEYWORDS] [a/KEYWORDS] [t/KEYWORDS] [n/ATTENDEE_NAME] [s/START e/END]` e.g., `findm m/Zoom Meet s/09.09.2023 0000 e/09.10.2023 0000` |
+| **Help** | `help` |
+| **List contacts** | `listc` |
+| **List meetings** | `listm` |
+| **Remove contact from meeting** | `rmmc MEETING_INDEX ATTENDEE_INDEX` e.g., `rmmc 2 2` |
+| **View contact details** | `viewc INDEX` e.g., `viewc 4` |
+| **View meeting details** | `viewm INDEX` e.g., `viewm 4` |
+| **Exit** | `exit` |
diff --git a/docs/diagrams/edit/CreateEditMeetingCommand.puml b/docs/diagrams/edit/CreateEditMeetingCommand.puml
new file mode 100644
index 00000000000..b54f366f2b4
--- /dev/null
+++ b/docs/diagrams/edit/CreateEditMeetingCommand.puml
@@ -0,0 +1,26 @@
+@startuml
+!include ../style.puml
+skinparam ArrowFontStyle plain
+
+title Create EditMeetingCommand
+
+Participant ":LogicManager" as logic LOGIC_COLOR
+Participant ":AddressBookParser" as abp LOGIC_COLOR
+Participant ":EditMeetingCommandParser" as emcp LOGIC_COLOR
+Participant "editMeetingDescriptor:EditMeetingDescriptor" as emd LOGIC_COLOR
+Participant "command:EditMeetingCommand" as emc LOGIC_COLOR
+
+activate logic
+logic -> abp ++: parseCommand(commandText)
+create emcp
+abp -> emcp ++: parse(arguments)
+create emd
+emcp -> emd ++: EditMeetingDescriptor()
+emd --> emcp --:
+create emc
+emcp -> emc ++: EditMeetingCommand(targetIndex, editMeetingDescriptor)
+emc --> emcp --: command
+emcp --> abp --: command
+abp --> logic --: command
+
+@enduml
diff --git a/docs/diagrams/edit/EditMeetingClassDiagram.puml b/docs/diagrams/edit/EditMeetingClassDiagram.puml
new file mode 100644
index 00000000000..8eef408cedd
--- /dev/null
+++ b/docs/diagrams/edit/EditMeetingClassDiagram.puml
@@ -0,0 +1,33 @@
+@startuml
+!include ../style.puml
+skinparam arrowThickness 1.1
+skinparam arrowColor LOGIC_COLOR_T4
+skinparam classBackgroundColor LOGIC_COLOR
+
+package Parser as ParserPackage {
+Class "<>\nParser" as Parser
+Class EditMeetingCommandParser
+}
+
+package Command as CommandPackage {
+Class EditMeetingCommand
+Class EditMeetingDescriptor
+Class "{abstract}\nCommand" as Command
+}
+
+Class Index
+Class AddressBookParser
+Class LogicManager
+
+AddressBookParser .down.> EditMeetingCommandParser : creates >
+EditMeetingCommandParser ..> EditMeetingCommand : creates >
+EditMeetingCommand -down->"1" EditMeetingDescriptor
+EditMeetingCommand -down->"1" Index
+EditMeetingCommand -left-|> Command
+EditMeetingCommandParser .down.|> Parser
+EditMeetingCommandParser .left.> EditMeetingDescriptor : creates >
+EditMeetingCommandParser .down.> Index : creates >
+LogicManager -right->"1" AddressBookParser
+LogicManager .down.> EditMeetingCommand : executes >
+
+@enduml
diff --git a/docs/diagrams/edit/EditMeetingSequenceDiagram.puml b/docs/diagrams/edit/EditMeetingSequenceDiagram.puml
new file mode 100644
index 00000000000..b5b28f9e3ef
--- /dev/null
+++ b/docs/diagrams/edit/EditMeetingSequenceDiagram.puml
@@ -0,0 +1,36 @@
+@startuml
+!include ../style.puml
+skinparam ArrowFontStyle plain
+
+title Execute EditMeetingCommand
+
+box Logic LOGIC_COLOR_T1
+Participant ":LogicManager" as logic LOGIC_COLOR
+Participant "command:EditMeetingCommand" as emc LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+Participant ":ModelManager" as model MODEL_COLOR
+Participant "editedMeeting:Meeting" as meet MODEL_COLOR
+end box
+
+[->logic : execute
+activate logic
+ref over logic, emc: Create EditMeetingCommand
+logic -> emc ++: execute(model)
+emc -> model ++: getFilteredMeetingList
+model --> emc --:
+emc -> emc ++: createEditedMeeting
+create meet
+emc -> meet ++: Meeting()
+meet --> emc --:
+emc --> emc --:
+emc -> model ++: setMeeting
+model --> emc --:
+emc -> model ++:updateFilteredMeetingList
+model --> emc --:
+emc --> logic --: CommandResult
+[<--logic
+deactivate logic
+
+@enduml
diff --git a/docs/diagrams/tracing/ViewContactCommandSequenceDiagram.puml b/docs/diagrams/view/CreateViewContactCommand.puml
similarity index 81%
rename from docs/diagrams/tracing/ViewContactCommandSequenceDiagram.puml
rename to docs/diagrams/view/CreateViewContactCommand.puml
index 503f59e25a8..5965e7773f1 100644
--- a/docs/diagrams/tracing/ViewContactCommandSequenceDiagram.puml
+++ b/docs/diagrams/view/CreateViewContactCommand.puml
@@ -2,7 +2,7 @@
!include ../style.puml
skinparam ArrowFontStyle plain
-title View Contact Command Sequence
+title Create ViewContactCommand
Participant ":LogicManager" as logic LOGIC_COLOR
Participant ":AddressBookParser" as abp LOGIC_COLOR
@@ -13,11 +13,10 @@ Participant "command:ViewContactCommand" as ec LOGIC_COLOR
activate logic
logic -> abp ++: parseCommand(commandText)
create vccp
-abp -> vccp
abp -> vccp ++: parse(arguments)
create ec
-vccp -> ec ++: index
-ec --> vccp --
+vccp -> ec ++: ViewContactCommand(targetIndex)
+ec --> vccp --: command
vccp --> abp --: command
abp --> logic --: command
diff --git a/docs/diagrams/tracing/UiViewItemsSequenceDiagram.puml b/docs/diagrams/view/UiViewItemsSequenceDiagram.puml
similarity index 100%
rename from docs/diagrams/tracing/UiViewItemsSequenceDiagram.puml
rename to docs/diagrams/view/UiViewItemsSequenceDiagram.puml
diff --git a/docs/diagrams/tracing/ViewCommandsSequenceDiagram.puml b/docs/diagrams/view/ViewCommandsSequenceDiagram.puml
similarity index 77%
rename from docs/diagrams/tracing/ViewCommandsSequenceDiagram.puml
rename to docs/diagrams/view/ViewCommandsSequenceDiagram.puml
index 0af839bb727..b3e1a94b255 100644
--- a/docs/diagrams/tracing/ViewCommandsSequenceDiagram.puml
+++ b/docs/diagrams/view/ViewCommandsSequenceDiagram.puml
@@ -2,11 +2,10 @@
!include ../style.puml
skinparam ArrowFontStyle plain
-title Store viewed Items to Model
+title Store Viewed Items to Model
box Logic LOGIC_COLOR_T1
Participant ":LogicManager" as logic LOGIC_COLOR
-Participant ":AddressBookParser" as abp LOGIC_COLOR
Participant "command:ViewContactCommand" as vcc LOGIC_COLOR
end box
@@ -16,7 +15,7 @@ end box
[->logic : execute
activate logic
-ref over logic, abp, vcc: View Contact Command Sequence
+ref over logic, vcc: Create ViewContactCommand
logic -> vcc ++: execute(model)
vcc -> model ++: setViewedPersonIndex(targetIndex)
model --> vcc --:
diff --git a/docs/images/edit/CreateEditMeetingCommand-Create_EditMeetingCommand.png b/docs/images/edit/CreateEditMeetingCommand-Create_EditMeetingCommand.png
new file mode 100644
index 00000000000..d316e441481
Binary files /dev/null and b/docs/images/edit/CreateEditMeetingCommand-Create_EditMeetingCommand.png differ
diff --git a/docs/images/edit/EditMeetingClassDiagram.png b/docs/images/edit/EditMeetingClassDiagram.png
new file mode 100644
index 00000000000..4cd6bd71403
Binary files /dev/null and b/docs/images/edit/EditMeetingClassDiagram.png differ
diff --git a/docs/images/edit/EditMeetingSequenceDiagram-Execute_EditMeetingCommand.png b/docs/images/edit/EditMeetingSequenceDiagram-Execute_EditMeetingCommand.png
new file mode 100644
index 00000000000..e398300911b
Binary files /dev/null and b/docs/images/edit/EditMeetingSequenceDiagram-Execute_EditMeetingCommand.png differ
diff --git a/docs/images/tracing/ViewCommandsSequenceDiagram-StoreViewedItemsToModel.png b/docs/images/tracing/ViewCommandsSequenceDiagram-StoreViewedItemsToModel.png
deleted file mode 100644
index 4f8906bca86..00000000000
Binary files a/docs/images/tracing/ViewCommandsSequenceDiagram-StoreViewedItemsToModel.png and /dev/null differ
diff --git a/docs/images/tracing/ViewContactCommandSequenceDiagram-ViewContactCommandSequence.png b/docs/images/tracing/ViewContactCommandSequenceDiagram-ViewContactCommandSequence.png
deleted file mode 100644
index fcb1ee82692..00000000000
Binary files a/docs/images/tracing/ViewContactCommandSequenceDiagram-ViewContactCommandSequence.png and /dev/null differ
diff --git a/docs/images/view/CreateViewContactCommand-Create_ViewContactCommand.png b/docs/images/view/CreateViewContactCommand-Create_ViewContactCommand.png
new file mode 100644
index 00000000000..07674e73baf
Binary files /dev/null and b/docs/images/view/CreateViewContactCommand-Create_ViewContactCommand.png differ
diff --git a/docs/images/tracing/UiViewItemsSequenceDiagram-ForwardViewedPerson&MeetingToUi.png b/docs/images/view/UiViewItemsSequenceDiagram-ForwardViewedPerson&MeetingToUi.png
similarity index 100%
rename from docs/images/tracing/UiViewItemsSequenceDiagram-ForwardViewedPerson&MeetingToUi.png
rename to docs/images/view/UiViewItemsSequenceDiagram-ForwardViewedPerson&MeetingToUi.png
diff --git a/docs/images/view/ViewCommandsSequenceDiagram-StoreViewedItemsToModel.png b/docs/images/view/ViewCommandsSequenceDiagram-StoreViewedItemsToModel.png
new file mode 100644
index 00000000000..a74ffd87ba4
Binary files /dev/null and b/docs/images/view/ViewCommandsSequenceDiagram-StoreViewedItemsToModel.png differ
diff --git a/docs/team/jason-raiin.md b/docs/team/jason-raiin.md
index 6040360fbf8..d1df38938a7 100644
--- a/docs/team/jason-raiin.md
+++ b/docs/team/jason-raiin.md
@@ -12,36 +12,40 @@ My contributions to the project are listed below.
- **New Feature**: Remove contact from meeting command
- Added command and parser
- - Thorough testing
+- **New Feature**: Mark meeting command
+ - Added command and parser
+ - Updates last contacted time for contacts
- **Code contributed**: [RepoSense link](https://nus-cs2103-ay2324s1.github.io/tp-dashboard/?search=jason-raiin&breakdown=true)
- **Project management**:
-
- - to be added soon
+ - Contributed issues
+ - Reviewed PRs
- **Enhancements to existing features**:
-
- - Add Tag to meetings: logic and UI
+ - Add Tags field to meetings
- Convert Tag to factory class with no duplicates
+ - Added Status field to meetings
- **Documentation**:
- User Guide
- - Remove meeting contact command
+ - `rmmc` command
+ - `mark` command
- Minor edits
- Developer Guide
+ - `rmmc` command
+ - `mark` command
- User profile
- Value proposition
- User stories
- Use cases
- **Community**:
-
- to be added soon
- **Tools**:
-
- Added util method `parseIndexes`
+ - Improved methods for `typicalMeetings` and `typicalAddressBook`
diff --git a/docs/team/lomaply.md b/docs/team/lomaply.md
index 4b2c3aeba4f..75a5068bdd2 100644
--- a/docs/team/lomaply.md
+++ b/docs/team/lomaply.md
@@ -26,7 +26,7 @@ My contributions to the project are listed below.
- Review and merge pull requests
- **Enhancements to existing features**:
-
+
- Sort contacts by last contacted time
- New Command
- "editm"
@@ -39,7 +39,7 @@ My contributions to the project are listed below.
- First draft of User Guide with initial plans for v1.2
- Update parts of User Guide on `viewm`, `viewc`, `editm`
- Developer Guide
- - Add Implementation notes on `viewm` & `viewc`
+ - Add Implementation notes on `viewm`, `viewc`, `editc` and `editm`
- **Community**:
diff --git a/src/main/java/seedu/address/logic/Messages.java b/src/main/java/seedu/address/logic/Messages.java
index 8a181503c7a..fa867f6e1d4 100644
--- a/src/main/java/seedu/address/logic/Messages.java
+++ b/src/main/java/seedu/address/logic/Messages.java
@@ -71,6 +71,8 @@ public static String format(Meeting meeting) {
.append(meeting.getEnd())
.append("; Attendees: ");
meeting.getAttendees().forEach(builder::append);
+ builder.append("; Completed: ")
+ .append(meeting.getStatus());
return builder.toString();
}
diff --git a/src/main/java/seedu/address/logic/commands/AddMeetingContactCommand.java b/src/main/java/seedu/address/logic/commands/AddMeetingContactCommand.java
index b348a8fa54e..90956474d43 100644
--- a/src/main/java/seedu/address/logic/commands/AddMeetingContactCommand.java
+++ b/src/main/java/seedu/address/logic/commands/AddMeetingContactCommand.java
@@ -79,7 +79,7 @@ static Meeting addAttendee(Meeting meeting, Attendee attendeeToAdd) {
Set updatedAttendees = new LinkedHashSet<>(meeting.getAttendees());
updatedAttendees.add(attendeeToAdd);
Meeting updatedMeeting = new Meeting(meeting.getTitle(), meeting.getLocation(), meeting.getStart(),
- meeting.getEnd(), updatedAttendees, meeting.getTags());
+ meeting.getEnd(), updatedAttendees, meeting.getTags(), meeting.getStatus());
return updatedMeeting;
}
diff --git a/src/main/java/seedu/address/logic/commands/EditMeetingCommand.java b/src/main/java/seedu/address/logic/commands/EditMeetingCommand.java
index 0dc569cad03..3cc3e9aa1f4 100644
--- a/src/main/java/seedu/address/logic/commands/EditMeetingCommand.java
+++ b/src/main/java/seedu/address/logic/commands/EditMeetingCommand.java
@@ -25,6 +25,7 @@
import seedu.address.model.meeting.Attendee;
import seedu.address.model.meeting.Location;
import seedu.address.model.meeting.Meeting;
+import seedu.address.model.meeting.MeetingStatus;
import seedu.address.model.meeting.MeetingTime;
import seedu.address.model.meeting.Title;
import seedu.address.model.tag.Tag;
@@ -102,12 +103,13 @@ static Meeting createEditedMeeting(Meeting meetingToEdit,
LocalDateTime updatedEnd = editMeetingDescriptor.getEnd().orElse(meetingToEdit.getEnd());
Set attendees = meetingToEdit.getAttendees();
Set updatedTags = editMeetingDescriptor.getTags().orElse(meetingToEdit.getTags());
+ MeetingStatus status = meetingToEdit.getStatus();
if (!MeetingTime.isValidMeetingTime(updatedStart, updatedEnd)) {
throw new CommandException(MeetingTime.MESSAGE_CONSTRAINTS);
}
- return new Meeting(updatedTitle, updatedLocation, updatedStart, updatedEnd, attendees, updatedTags);
+ return new Meeting(updatedTitle, updatedLocation, updatedStart, updatedEnd, attendees, updatedTags, status);
}
@Override
diff --git a/src/main/java/seedu/address/logic/commands/FindMeetingCommand.java b/src/main/java/seedu/address/logic/commands/FindMeetingCommand.java
index a7f06bef8d1..ae87b33ca79 100644
--- a/src/main/java/seedu/address/logic/commands/FindMeetingCommand.java
+++ b/src/main/java/seedu/address/logic/commands/FindMeetingCommand.java
@@ -34,7 +34,7 @@ public class FindMeetingCommand extends Command {
* @param predicate The predicate that will be used by the FindMeetingCommand object.
*/
public FindMeetingCommand(GeneralMeetingPredicate predicate) {
- assert predicate != null;
+ requireNonNull(predicate);
this.predicate = predicate;
}
diff --git a/src/main/java/seedu/address/logic/commands/MarkMeetingCommand.java b/src/main/java/seedu/address/logic/commands/MarkMeetingCommand.java
new file mode 100644
index 00000000000..139af978911
--- /dev/null
+++ b/src/main/java/seedu/address/logic/commands/MarkMeetingCommand.java
@@ -0,0 +1,105 @@
+package seedu.address.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+
+import java.time.LocalDateTime;
+import java.util.Iterator;
+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.meeting.Attendee;
+import seedu.address.model.meeting.Meeting;
+import seedu.address.model.meeting.MeetingStatus;
+import seedu.address.model.person.Person;
+
+/**
+ * Marks a meeting as complete.
+ */
+public class MarkMeetingCommand extends Command {
+
+ public static final String COMMAND_WORD = "mark";
+
+ public static final String MESSAGE_MARK_MEETING_SUCCESS = "Meeting marked as complete: %1$s";
+
+ public static final String MESSAGE_MEETING_ALREADY_COMPLETE = "Meeting has already been marked as complete.";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD
+ + ": Marks the meeting identified by the index number used in the displayed meetings list as complete.\n"
+ + "Parameters: INDEX (must be a positive integer)\n" + "Example: " + COMMAND_WORD + "1";
+
+ private final Index targetIndex;
+
+ public MarkMeetingCommand(Index targetIndex) {
+ this.targetIndex = targetIndex;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+ List lastShownList = model.getFilteredMeetingList();
+
+ if (targetIndex.getZeroBased() >= lastShownList.size()) {
+ throw new CommandException(Messages.MESSAGE_INVALID_MEETING_DISPLAYED_INDEX);
+ }
+
+ Meeting meetingToMark = lastShownList.get(targetIndex.getZeroBased());
+ Meeting updatedMeeting = markMeeting(meetingToMark);
+ model.setMeeting(meetingToMark, updatedMeeting);
+
+ Iterator attendeeIterator = meetingToMark.getAttendees().iterator();
+ while (attendeeIterator.hasNext()) {
+ Attendee attendee = attendeeIterator.next();
+ Person person = model.getPerson(attendee.getAttendeeName());
+ Person updatedPerson = updateLastContactedTime(person, meetingToMark.getEnd());
+ model.setPerson(person, updatedPerson);
+ }
+
+ return new CommandResult(String.format(MESSAGE_MARK_MEETING_SUCCESS, Messages.format(updatedMeeting)));
+ }
+
+ static Meeting markMeeting(Meeting meeting) throws CommandException {
+ if (meeting.getStatus().isComplete) {
+ throw new CommandException(MESSAGE_MEETING_ALREADY_COMPLETE);
+ }
+
+ Meeting markedMeeting = new Meeting(meeting.getTitle(), meeting.getLocation(), meeting.getStart(),
+ meeting.getEnd(), meeting.getAttendees(), meeting.getTags(), new MeetingStatus(true));
+
+ return markedMeeting;
+ }
+
+ static Person updateLastContactedTime(Person person, LocalDateTime lastContactedTime) {
+ if (lastContactedTime.isBefore(person.getLastContactedTime())) {
+ return person;
+ }
+
+ Person updatedPerson = new Person(person.getName(), person.getPhone(), person.getEmail(), lastContactedTime,
+ person.getStatus(), person.getRemark(), person.getTags());
+
+ return updatedPerson;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof MarkMeetingCommand)) {
+ return false;
+ }
+
+ MarkMeetingCommand otherMarkMeetingCommand = (MarkMeetingCommand) other;
+ return targetIndex.equals(otherMarkMeetingCommand.targetIndex);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).add("targetIndex", targetIndex).toString();
+ }
+}
diff --git a/src/main/java/seedu/address/logic/commands/RemoveMeetingContactCommand.java b/src/main/java/seedu/address/logic/commands/RemoveMeetingContactCommand.java
index 2b12de4252e..e0f0c163370 100644
--- a/src/main/java/seedu/address/logic/commands/RemoveMeetingContactCommand.java
+++ b/src/main/java/seedu/address/logic/commands/RemoveMeetingContactCommand.java
@@ -68,7 +68,7 @@ static Meeting removeAttendee(Meeting meeting, Attendee attendeeToRemove) {
Set updatedAttendees = new LinkedHashSet<>(meeting.getAttendees());
updatedAttendees.remove(attendeeToRemove);
Meeting updatedMeeting = new Meeting(meeting.getTitle(), meeting.getLocation(), meeting.getStart(),
- meeting.getEnd(), updatedAttendees, meeting.getTags());
+ meeting.getEnd(), updatedAttendees, meeting.getTags(), meeting.getStatus());
return updatedMeeting;
}
diff --git a/src/main/java/seedu/address/logic/parser/AddMeetingCommandParser.java b/src/main/java/seedu/address/logic/parser/AddMeetingCommandParser.java
index c8b4d780313..8c01d89c298 100644
--- a/src/main/java/seedu/address/logic/parser/AddMeetingCommandParser.java
+++ b/src/main/java/seedu/address/logic/parser/AddMeetingCommandParser.java
@@ -20,6 +20,7 @@
import seedu.address.model.meeting.Attendee;
import seedu.address.model.meeting.Location;
import seedu.address.model.meeting.Meeting;
+import seedu.address.model.meeting.MeetingStatus;
import seedu.address.model.meeting.MeetingTime;
import seedu.address.model.meeting.Title;
import seedu.address.model.tag.Tag;
@@ -56,8 +57,9 @@ public AddMeetingCommand parse(String args) throws ParseException {
}
Set attendeeList = ParserUtil.parseAttendees(argMultimap.getAllValues(PREFIX_NAME));
Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG));
+ MeetingStatus status = new MeetingStatus(false);
- Meeting meeting = new Meeting(title, location, start, end, attendeeList, tagList);
+ Meeting meeting = new Meeting(title, location, start, end, attendeeList, tagList, status);
return new AddMeetingCommand(meeting);
}
diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java
index e437598624d..918ae644c32 100644
--- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java
+++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java
@@ -23,6 +23,7 @@
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.commands.ListMeetingCommand;
+import seedu.address.logic.commands.MarkMeetingCommand;
import seedu.address.logic.commands.RemoveMeetingContactCommand;
import seedu.address.logic.commands.ViewContactCommand;
import seedu.address.logic.commands.ViewMeetingCommand;
@@ -113,6 +114,9 @@ public Command parseCommand(String userInput) throws ParseException {
case FindMeetingCommand.COMMAND_WORD:
return new FindMeetingCommandParser().parse(arguments);
+ case MarkMeetingCommand.COMMAND_WORD:
+ return new MarkMeetingCommandParser().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/MarkMeetingCommandParser.java b/src/main/java/seedu/address/logic/parser/MarkMeetingCommandParser.java
new file mode 100644
index 00000000000..07deae8d5be
--- /dev/null
+++ b/src/main/java/seedu/address/logic/parser/MarkMeetingCommandParser.java
@@ -0,0 +1,29 @@
+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.MarkMeetingCommand;
+import seedu.address.logic.parser.exceptions.ParseException;
+
+/**
+ * Parses input arguments and creates a new MarkMeetingCommand object
+ */
+public class MarkMeetingCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the MarkMeetingCommand
+ * and returns a MarkMeetingCommand object for execution.
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public MarkMeetingCommand parse(String args) throws ParseException {
+ try {
+ Index index = ParserUtil.parseIndex(args);
+ return new MarkMeetingCommand(index);
+ } catch (ParseException pe) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, MarkMeetingCommand.MESSAGE_USAGE), pe);
+ }
+ }
+
+}
diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java
index 90be75d873a..d4eb0bc493d 100644
--- a/src/main/java/seedu/address/model/AddressBook.java
+++ b/src/main/java/seedu/address/model/AddressBook.java
@@ -109,6 +109,14 @@ public void addMeeting(Meeting m) {
meetings.add(m);
}
+ /**
+ * Returns the person with the given name
+ * or throws {@code IndexOutOfBoundsException} if it does not exist.
+ */
+ public Person getPerson(String name) {
+ return persons.getPerson(name);
+ }
+
/**
* Replaces the given person {@code target} in the list with {@code editedPerson}.
* {@code target} must exist in the address book.
diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java
index 8d7ddd20905..53de634126b 100644
--- a/src/main/java/seedu/address/model/Model.java
+++ b/src/main/java/seedu/address/model/Model.java
@@ -90,6 +90,12 @@ public interface Model {
*/
void addMeeting(Meeting meeting);
+ /**
+ * Returns the person with the given name.
+ * A person with the given name must exist in the address book.
+ */
+ Person getPerson(String name);
+
/**
* Replaces the given person {@code target} with {@code editedPerson}.
* {@code target} must exist in the address book.
diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java
index 09a34df0081..a86ed002641 100644
--- a/src/main/java/seedu/address/model/ModelManager.java
+++ b/src/main/java/seedu/address/model/ModelManager.java
@@ -136,6 +136,11 @@ public void addMeeting(Meeting meeting) {
updateFilteredMeetingList(PREDICATE_SHOW_ALL_MEETINGS);
}
+ @Override
+ public Person getPerson(String name) {
+ return addressBook.getPerson(name);
+ }
+
@Override
public void setPerson(Person target, Person editedPerson) {
requireAllNonNull(target, editedPerson);
diff --git a/src/main/java/seedu/address/model/meeting/Meeting.java b/src/main/java/seedu/address/model/meeting/Meeting.java
index c6bbcbd007c..b57d98baafc 100644
--- a/src/main/java/seedu/address/model/meeting/Meeting.java
+++ b/src/main/java/seedu/address/model/meeting/Meeting.java
@@ -24,17 +24,19 @@ public class Meeting {
private final MeetingTime meetingTime;
private final Set attendees;
private final Set tags;
+ private final MeetingStatus status;
/**
* Every field must be present and not null.
*/
public Meeting(Title title, Location location, LocalDateTime start, LocalDateTime end, Set attendees,
- Set tags) {
+ Set tags, MeetingStatus status) {
this.title = title;
this.location = location;
this.meetingTime = new MeetingTime(start, end);
this.attendees = new LinkedHashSet<>(attendees);
this.tags = new HashSet<>(tags);
+ this.status = status;
}
public Title getTitle() {
@@ -57,6 +59,10 @@ public MeetingTime getMeetingTime() {
return meetingTime;
}
+ public MeetingStatus getStatus() {
+ return status;
+ }
+
public boolean withinSpecifiedTime(LocalDateTime start, LocalDateTime end) {
return !meetingTime.getStart().isBefore(start) && !meetingTime.getEnd().isAfter(end);
}
@@ -135,7 +141,7 @@ public boolean equals(Object other) {
Meeting otherMeeting = (Meeting) other;
return title.equals(otherMeeting.title) && location.equals(otherMeeting.location)
&& meetingTime.equals(otherMeeting.meetingTime) && attendees.equals(otherMeeting.attendees)
- && tags.equals(otherMeeting.tags);
+ && tags.equals(otherMeeting.tags) && status.equals(otherMeeting.status);
}
@Override
@@ -148,7 +154,7 @@ public int hashCode() {
public String toString() {
return new ToStringBuilder(this).add("title", title).add("location", location)
.add("start", meetingTime.getStart()).add("end", meetingTime.getEnd()).add("attendees", attendees)
- .add("tags", tags).toString();
+ .add("tags", tags).add("status", status).toString();
}
/**
diff --git a/src/main/java/seedu/address/model/meeting/MeetingStatus.java b/src/main/java/seedu/address/model/meeting/MeetingStatus.java
new file mode 100644
index 00000000000..011ecaad3e6
--- /dev/null
+++ b/src/main/java/seedu/address/model/meeting/MeetingStatus.java
@@ -0,0 +1,44 @@
+package seedu.address.model.meeting;
+
+/**
+ * Contains a Boolean representing whether a meeting is completed.
+ */
+public class MeetingStatus {
+
+ public static final String MESSAGE_CONSTRAINTS = "Status must be exactly 'true' or 'false'";
+ public final Boolean isComplete;
+
+ /**
+ * Constructs a {@code Status} field representing whether a meeting is complete.
+ */
+ public MeetingStatus(Boolean isComplete) {
+ this.isComplete = isComplete;
+ }
+
+ @Override
+ public int hashCode() {
+ return isComplete.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof MeetingStatus)) {
+ return false;
+ }
+
+ MeetingStatus completed = (MeetingStatus) other;
+ return isComplete.equals(completed.isComplete);
+ }
+
+ /**
+ * Format state as text for viewing.
+ */
+ @Override
+ public String toString() {
+ return isComplete.toString();
+ }
+}
diff --git a/src/main/java/seedu/address/model/person/UniquePersonList.java b/src/main/java/seedu/address/model/person/UniquePersonList.java
index 1bf241c0c32..22536919254 100644
--- a/src/main/java/seedu/address/model/person/UniquePersonList.java
+++ b/src/main/java/seedu/address/model/person/UniquePersonList.java
@@ -66,6 +66,21 @@ public void add(Person toAdd) {
FXCollections.sort(internalList, sortByLastContactComparator);
}
+ /**
+ * Returns the person with the given name
+ * or throws {@code IndexOutOfBoundsException} if it does not exist.
+ */
+ public Person getPerson(String fullName) {
+ Name name = new Name(fullName);
+ List filteredList = internalList.filtered(person -> person.getName().equals(name));
+
+ if (filteredList.size() == 0) {
+ throw new PersonNotFoundException();
+ }
+
+ return filteredList.get(0);
+ }
+
/**
* Replaces the person {@code target} in the list with {@code editedPerson}.
* {@code target} must exist in the list.
diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java
index 9096dcd8915..5d4bcb4937b 100644
--- a/src/main/java/seedu/address/model/util/SampleDataUtil.java
+++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java
@@ -13,6 +13,7 @@
import seedu.address.model.meeting.Attendee;
import seedu.address.model.meeting.Location;
import seedu.address.model.meeting.Meeting;
+import seedu.address.model.meeting.MeetingStatus;
import seedu.address.model.meeting.Title;
import seedu.address.model.person.Email;
import seedu.address.model.person.Name;
@@ -54,11 +55,11 @@ public static Meeting[] getSampleMeetings() {
new Meeting(new Title("Test Meeting 1"), new Location("Room 1"),
LocalDateTime.parse("02.10.2023 1000", FORMAT),
LocalDateTime.parse("03.10.2023 1000", FORMAT),
- getAttendeeSet("Alex Yeoh"), getTagSet("work")),
+ getAttendeeSet("Alex Yeoh"), getTagSet("work"), new MeetingStatus(false)),
new Meeting(new Title("Test Meeting 2"), new Location("Room 2"),
LocalDateTime.parse("02.10.2023 1000", FORMAT),
LocalDateTime.parse("02.10.2023 1000", FORMAT),
- getAttendeeSet(), getTagSet()),
+ getAttendeeSet(), getTagSet(), new MeetingStatus(false)),
};
}
diff --git a/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java b/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java
index 702ee11d3cb..a9b8f4bfb24 100644
--- a/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java
+++ b/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java
@@ -15,6 +15,7 @@
import seedu.address.model.meeting.Attendee;
import seedu.address.model.meeting.Location;
import seedu.address.model.meeting.Meeting;
+import seedu.address.model.meeting.MeetingStatus;
import seedu.address.model.meeting.MeetingTime;
import seedu.address.model.meeting.Title;
import seedu.address.model.tag.Tag;
@@ -32,6 +33,7 @@ class JsonAdaptedMeeting {
private final String end;
private final List attendees = new ArrayList<>();
private final List tags = new ArrayList<>();
+ private final String status;
/**
* Constructs a {@code JsonAdaptedPerson} with the given person details.
@@ -40,7 +42,7 @@ class JsonAdaptedMeeting {
public JsonAdaptedMeeting(@JsonProperty("title") String title, @JsonProperty("location") String location,
@JsonProperty("start") String start, @JsonProperty("end") String end,
@JsonProperty("attendees") List attendees,
- @JsonProperty("tags") List tags) {
+ @JsonProperty("tags") List tags, @JsonProperty("status") String status) {
this.title = title;
this.location = location;
@@ -52,6 +54,7 @@ public JsonAdaptedMeeting(@JsonProperty("title") String title, @JsonProperty("lo
if (tags != null) {
this.tags.addAll(tags);
}
+ this.status = status;
}
/**
@@ -68,6 +71,7 @@ public JsonAdaptedMeeting(Meeting source) {
tags.addAll(source.getTags().stream()
.map(JsonAdaptedTag::new)
.collect(Collectors.toList()));
+ status = source.getStatus().toString();
}
/**
@@ -80,11 +84,13 @@ public Meeting toModelType() throws IllegalValueException {
for (JsonAdaptedAttendee person : attendees) {
meetingAttendees.add(person.toModelType());
}
+ final Set modelAttendees = new HashSet<>(meetingAttendees);
final List meetingTags = new ArrayList<>();
for (JsonAdaptedTag tag : tags) {
meetingTags.add(tag.toModelType());
}
+ final Set modelTags = new HashSet<>(meetingTags);
if (title == null) {
throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT,
@@ -118,10 +124,16 @@ public Meeting toModelType() throws IllegalValueException {
final LocalDateTime modelStart = LocalDateTime.parse(start);
final LocalDateTime modelEnd = LocalDateTime.parse(end);
- final Set modelAttendees = new HashSet<>(meetingAttendees);
+ if (status == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT,
+ MeetingStatus.class.getSimpleName()));
+ }
+ if (!status.equals(Boolean.FALSE.toString()) && !status.equals(Boolean.TRUE.toString())) {
+ throw new IllegalValueException(MeetingStatus.MESSAGE_CONSTRAINTS);
+ }
+ final MeetingStatus modelStatus = new MeetingStatus(Boolean.parseBoolean(status));
- final Set modelTags = new HashSet<>(meetingTags);
- return new Meeting(modelTitle, modelLocation, modelStart, modelEnd, modelAttendees, modelTags);
+ return new Meeting(modelTitle, modelLocation, modelStart, modelEnd, modelAttendees, modelTags, modelStatus);
}
}
diff --git a/src/main/java/seedu/address/ui/MeetingCard.java b/src/main/java/seedu/address/ui/MeetingCard.java
index 50b1eb487fa..242de1f7d44 100644
--- a/src/main/java/seedu/address/ui/MeetingCard.java
+++ b/src/main/java/seedu/address/ui/MeetingCard.java
@@ -50,6 +50,8 @@ public class MeetingCard extends UiPart {
private Label end;
@FXML
private FlowPane tags;
+ @FXML
+ private Label status;
/**
* Creates a {@code MeetingCode} with the given {@code Meeting} and index to display.
@@ -71,5 +73,10 @@ public MeetingCard(Meeting meeting, int displayedIndex) {
meeting.getTags().stream()
.sorted(Comparator.comparing(tag -> tag.tagName))
.forEach(tag -> tags.getChildren().add(new Label(tag.tagName)));
+ if (meeting.getStatus().isComplete) {
+ status.setText("[COMPLETE]");
+ } else {
+ status.setText("");
+ }
}
}
diff --git a/src/main/resources/view/MeetingScheduleCard.fxml b/src/main/resources/view/MeetingScheduleCard.fxml
index 9b20050fec1..330e62b9bf7 100644
--- a/src/main/resources/view/MeetingScheduleCard.fxml
+++ b/src/main/resources/view/MeetingScheduleCard.fxml
@@ -28,6 +28,9 @@
+
+
+
@@ -37,14 +40,14 @@
-
-
-
+
+
+
-
-
-
+
+
+
diff --git a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java
index 162a0c86031..9c4e209a230 100644
--- a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java
+++ b/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java
@@ -2,7 +2,7 @@
import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
diff --git a/src/test/java/seedu/address/logic/commands/AddCommandTest.java b/src/test/java/seedu/address/logic/commands/AddCommandTest.java
index a84d3e4b1b7..c2759c0e897 100644
--- a/src/test/java/seedu/address/logic/commands/AddCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/AddCommandTest.java
@@ -131,6 +131,11 @@ public void addMeeting(Meeting meeting) {
throw new AssertionError("This method should not be called.");
}
+ @Override
+ public Person getPerson(String name) {
+ throw new AssertionError("This method should not be called.");
+ }
+
@Override
public void setAddressBook(ReadOnlyAddressBook newData) {
throw new AssertionError("This method should not be called.");
@@ -148,7 +153,7 @@ public boolean hasPerson(Person person) {
@Override
public boolean hasMeeting(Meeting meeting) {
- return false;
+ throw new AssertionError("This method should not be called.");
}
@Override
@@ -188,7 +193,7 @@ public ObservableList getFilteredPersonList() {
@Override
public ObservableList getFilteredMeetingList() {
- return null;
+ throw new AssertionError("This method should not be called.");
}
@Override
@@ -203,7 +208,7 @@ public void updateFilteredMeetingList(Predicate predicate) {
@Override
public boolean hasName(String attendeeName) {
- return false;
+ throw new AssertionError("This method should not be called.");
}
@Override
diff --git a/src/test/java/seedu/address/logic/commands/AddMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/AddMeetingCommandTest.java
index 781f72f2e7f..914a2fa13c9 100644
--- a/src/test/java/seedu/address/logic/commands/AddMeetingCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/AddMeetingCommandTest.java
@@ -132,6 +132,11 @@ public void addMeeting(Meeting meeting) {
throw new AssertionError("This method should not be called.");
}
+ @Override
+ public Person getPerson(String name) {
+ throw new AssertionError("This method should not be called.");
+ }
+
@Override
public void setAddressBook(ReadOnlyAddressBook newData) {
throw new AssertionError("This method should not be called.");
@@ -149,7 +154,7 @@ public boolean hasPerson(Person person) {
@Override
public boolean hasMeeting(Meeting meeting) {
- return false;
+ throw new AssertionError("This method should not be called.");
}
@Override
@@ -189,7 +194,7 @@ public ObservableList getFilteredPersonList() {
@Override
public ObservableList getFilteredMeetingList() {
- return null;
+ throw new AssertionError("This method should not be called.");
}
@Override
@@ -204,7 +209,7 @@ public void updateFilteredMeetingList(Predicate predicate) {
@Override
public boolean hasName(String attendeeName) {
- return false;
+ throw new AssertionError("This method should not be called.");
}
diff --git a/src/test/java/seedu/address/logic/commands/AddMeetingContactCommandTest.java b/src/test/java/seedu/address/logic/commands/AddMeetingContactCommandTest.java
index c8e1f8602ae..154e1968d33 100644
--- a/src/test/java/seedu/address/logic/commands/AddMeetingContactCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/AddMeetingContactCommandTest.java
@@ -5,14 +5,12 @@
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 seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook;
import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_MEETING;
import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
import static seedu.address.testutil.TypicalIndexes.INDEX_OUT_OF_BOUNDS;
import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_MEETING;
import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
-
-import java.util.Arrays;
import org.junit.jupiter.api.Test;
@@ -23,8 +21,6 @@
import seedu.address.model.meeting.Meeting;
import seedu.address.model.person.Person;
import seedu.address.testutil.MeetingBuilder;
-import seedu.address.testutil.TypicalMeetings;
-import seedu.address.testutil.TypicalPersons;
/**
* Contains integration tests (interaction with the Model) and unit tests for
@@ -36,7 +32,6 @@ public class AddMeetingContactCommandTest {
@Test
public void execute_valid_success() {
- model.addMeeting(TypicalMeetings.MEETING2);
AddMeetingContactCommand addmcCommand = new AddMeetingContactCommand(INDEX_FIRST_MEETING,
INDEX_FIRST_PERSON);
@@ -53,7 +48,7 @@ public void execute_valid_success() {
assertEquals(expectedMessage, message);
Meeting updatedMeeting = model.getFilteredMeetingList().get(INDEX_FIRST_MEETING.getZeroBased());
- String[] expectedAttendees = Arrays.copyOfRange(TypicalPersons.getTypicalAttendees(), 0, 7);
+ String[] expectedAttendees = new String[] { personToAdd.getName().fullName };
Meeting expectedMeeting = new MeetingBuilder(meeting)
.withAttendees(expectedAttendees)
.build();
@@ -64,7 +59,7 @@ public void execute_valid_success() {
@Test
public void execute_invalidMeetingIndex_throwsCommandException() {
- AddMeetingContactCommand addmcCommand = new AddMeetingContactCommand(INDEX_SECOND_MEETING,
+ AddMeetingContactCommand addmcCommand = new AddMeetingContactCommand(INDEX_OUT_OF_BOUNDS,
INDEX_FIRST_PERSON);
// throws error for invalid meeting index
@@ -73,7 +68,6 @@ public void execute_invalidMeetingIndex_throwsCommandException() {
@Test
public void execute_invalidContactIndex_throwsCommandException() {
- model.addMeeting(TypicalMeetings.MEETING1);
AddMeetingContactCommand addmcCommand = new AddMeetingContactCommand(INDEX_FIRST_MEETING,
INDEX_OUT_OF_BOUNDS);
@@ -83,10 +77,12 @@ public void execute_invalidContactIndex_throwsCommandException() {
@Test
public void execute_duplicateAttendee_throwsCommandException() {
- model.addMeeting(TypicalMeetings.MEETING1);
AddMeetingContactCommand addmcCommand = new AddMeetingContactCommand(INDEX_FIRST_MEETING,
INDEX_FIRST_PERSON);
+ // does not throw the first time
+ assertDoesNotThrow(() -> addmcCommand.execute(model));
+
// throws error for duplicate attendee
assertThrows(CommandException.class, () -> addmcCommand.execute(model));
}
diff --git a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java
index 80d9110c03a..126b56ad8ca 100644
--- a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java
@@ -1,7 +1,7 @@
package seedu.address.logic.commands;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook;
import org.junit.jupiter.api.Test;
diff --git a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java
index 7cf541725c1..3f11414a712 100644
--- a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java
@@ -6,9 +6,9 @@
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.TypicalAddressBook.getTypicalAddressBook;
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;
diff --git a/src/test/java/seedu/address/logic/commands/DeleteMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteMeetingCommandTest.java
index 2aff097f7db..48753377d0d 100644
--- a/src/test/java/seedu/address/logic/commands/DeleteMeetingCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/DeleteMeetingCommandTest.java
@@ -6,9 +6,9 @@
import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
import static seedu.address.logic.commands.CommandTestUtil.showMeetingAtIndex;
+import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook;
import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_MEETING;
import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_MEETING;
-import static seedu.address.testutil.TypicalMeetings.getTypicalAddressBook;
import org.junit.jupiter.api.Test;
diff --git a/src/test/java/seedu/address/logic/commands/EditCommandTest.java b/src/test/java/seedu/address/logic/commands/EditCommandTest.java
index cd095cccf01..7732d417cbf 100644
--- a/src/test/java/seedu/address/logic/commands/EditCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/EditCommandTest.java
@@ -11,9 +11,9 @@
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.TypicalAddressBook.getTypicalAddressBook;
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;
diff --git a/src/test/java/seedu/address/logic/commands/EditMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/EditMeetingCommandTest.java
index f9c19d37472..4d78b94bace 100644
--- a/src/test/java/seedu/address/logic/commands/EditMeetingCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/EditMeetingCommandTest.java
@@ -12,9 +12,9 @@
import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
import static seedu.address.logic.commands.CommandTestUtil.showMeetingAtIndex;
+import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook;
import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_MEETING;
import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_MEETING;
-import static seedu.address.testutil.TypicalMeetings.getTypicalAddressBook;
import org.junit.jupiter.api.Test;
@@ -43,16 +43,16 @@ public class EditMeetingCommandTest {
@Test
public void execute_allFieldsSpecifiedUnfilteredList_success() {
// Attendees field do not get edited by this command.
- Meeting editedMeeting = new MeetingBuilder().withAttendees(TypicalPersons.getTypicalAttendees()).build();
+ Meeting editedMeeting = new MeetingBuilder().withAttendees(TypicalPersons.getTypicalAttendeesSubset1()).build();
EditMeetingDescriptor descriptor = new EditMeetingDescriptorBuilder(editedMeeting).build();
- EditMeetingCommand editMeetingCommand = new EditMeetingCommand(INDEX_FIRST_MEETING, descriptor);
+ EditMeetingCommand editMeetingCommand = new EditMeetingCommand(INDEX_SECOND_MEETING, descriptor);
String expectedMessage = String.format(EditMeetingCommand.MESSAGE_EDIT_MEETING_SUCCESS,
Messages.format(editedMeeting));
Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs());
- expectedModel.setMeeting(model.getFilteredMeetingList().get(0), editedMeeting);
+ expectedModel.setMeeting(model.getFilteredMeetingList().get(1), editedMeeting);
assertCommandSuccess(editMeetingCommand, model, expectedMessage, expectedModel);
}
diff --git a/src/test/java/seedu/address/logic/commands/FindCommandTest.java b/src/test/java/seedu/address/logic/commands/FindCommandTest.java
index 312a46ad551..94885d928d9 100644
--- a/src/test/java/seedu/address/logic/commands/FindCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/FindCommandTest.java
@@ -6,6 +6,7 @@
import static seedu.address.logic.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
import static seedu.address.logic.parser.ParserUtil.FORMAT;
+import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook;
import static seedu.address.testutil.TypicalPersons.ALICE;
import static seedu.address.testutil.TypicalPersons.BENSON;
import static seedu.address.testutil.TypicalPersons.CARL;
@@ -14,7 +15,6 @@
import static seedu.address.testutil.TypicalPersons.FIONA;
import static seedu.address.testutil.TypicalPersons.GEORGE;
import static seedu.address.testutil.TypicalPersons.HOON;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
import java.time.LocalDate;
import java.time.LocalDateTime;
diff --git a/src/test/java/seedu/address/logic/commands/FindMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/FindMeetingCommandTest.java
index fc260150d42..30ab630b947 100644
--- a/src/test/java/seedu/address/logic/commands/FindMeetingCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/FindMeetingCommandTest.java
@@ -5,6 +5,7 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import static seedu.address.logic.Messages.MESSAGE_MEETINGS_LISTED_OVERVIEW;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook;
import static seedu.address.testutil.TypicalMeetings.MEETING1;
import static seedu.address.testutil.TypicalMeetings.MEETING2;
import static seedu.address.testutil.TypicalMeetings.MEETING3;
@@ -27,17 +28,16 @@
import seedu.address.model.meeting.MeetingTagContainsKeywordsPredicate;
import seedu.address.model.meeting.MeetingTimeContainsPredicate;
import seedu.address.model.meeting.TitleContainsKeywordsPredicate;
-import seedu.address.testutil.TypicalMeetings;
/**
* Contains integration tests (interaction with the Model) for {@code FindMeetingCommand}.
*/
public class FindMeetingCommandTest {
- private Model model = new ModelManager(TypicalMeetings.getTypicalAddressBook(), new UserPrefs());
- private Model expectedModel = new ModelManager(TypicalMeetings.getTypicalAddressBook(), new UserPrefs());
+ private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs());
private LocalDateTime start = LocalDateTime.of(LocalDate.of(0001, 01, 01), LocalTime.of(00, 00));
- private LocalDateTime startOn30 = LocalDateTime.of(LocalDate.of(2023, 9, 30), LocalTime.of(10, 00));
- private LocalDateTime endOn30 = LocalDateTime.of(LocalDate.of(2023, 9, 30), LocalTime.of(12, 00));
+ private LocalDateTime startOn30 = LocalDateTime.of(LocalDate.of(2023, 11, 30), LocalTime.of(10, 00));
+ private LocalDateTime endOn30 = LocalDateTime.of(LocalDate.of(2023, 11, 30), LocalTime.of(12, 00));
private LocalDateTime start2 = LocalDateTime.of(LocalDate.of(0001, 01, 02), LocalTime.of(00, 00));
private LocalDateTime end = LocalDateTime.of(LocalDate.of(9999, 12, 31), LocalTime.of(23, 59));
@Test
@@ -138,26 +138,26 @@ public void execute_multipleTitleAndMultipleLocationKeywords_oneMeetingFound() {
@Test
public void execute_multipleTitleMultipleLocationAndAttendeeKeywords_twoMeetingFound() {
- String expectedMessage = String.format(MESSAGE_MEETINGS_LISTED_OVERVIEW, 2);
+ String expectedMessage = String.format(MESSAGE_MEETINGS_LISTED_OVERVIEW, 1);
GeneralMeetingPredicate predicate =
preparePredicate(new String[]{"ABCDE CS2101", "Zoom com", "Hoon", ""},
start, end);
FindMeetingCommand command = new FindMeetingCommand(predicate);
expectedModel.updateFilteredMeetingList(predicate);
assertCommandSuccess(command, model, expectedMessage, expectedModel);
- assertEquals(Arrays.asList(MEETING3, MEETING4), model.getFilteredMeetingList());
+ assertEquals(Arrays.asList(MEETING4), model.getFilteredMeetingList());
}
@Test
public void execute_multipleTitleMultipleLocationAndMultipleAttendeeKeywords_twoMeetingFound() {
- String expectedMessage = String.format(MESSAGE_MEETINGS_LISTED_OVERVIEW, 3);
+ String expectedMessage = String.format(MESSAGE_MEETINGS_LISTED_OVERVIEW, 2);
GeneralMeetingPredicate predicate =
preparePredicate(new String[]{"ABCDE CS2101", "Zoom com", "Alice Benson", ""},
start, end);
FindMeetingCommand command = new FindMeetingCommand(predicate);
expectedModel.updateFilteredMeetingList(predicate);
assertCommandSuccess(command, model, expectedMessage, expectedModel);
- assertEquals(Arrays.asList(MEETING2, MEETING3, MEETING4), model.getFilteredMeetingList());
+ assertEquals(Arrays.asList(MEETING3, MEETING4), model.getFilteredMeetingList());
}
@Test
@@ -188,7 +188,7 @@ public void execute_multipleTitleMultipleLocationMultipleAttendeeMultipleTagKeyw
public void execute_titleLocationAttendeeTagTimeKeywords_oneMeetingFound() {
String expectedMessage = String.format(MESSAGE_MEETINGS_LISTED_OVERVIEW, 1);
GeneralMeetingPredicate predicate =
- preparePredicate(new String[]{"ABCDE CS2101", "Zoom com", "Alice Benson", "work important"},
+ preparePredicate(new String[]{"ABCDE CS2101", "Zoom com", "", "work important"},
startOn30, endOn30);
FindMeetingCommand command = new FindMeetingCommand(predicate);
expectedModel.updateFilteredMeetingList(predicate);
diff --git a/src/test/java/seedu/address/logic/commands/ListCommandTest.java b/src/test/java/seedu/address/logic/commands/ListCommandTest.java
index 435ff1f7275..12d9e84b7fb 100644
--- a/src/test/java/seedu/address/logic/commands/ListCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/ListCommandTest.java
@@ -2,8 +2,8 @@
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex;
+import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook;
import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
diff --git a/src/test/java/seedu/address/logic/commands/ListMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/ListMeetingCommandTest.java
index a8ec94a2493..8e70beea92e 100644
--- a/src/test/java/seedu/address/logic/commands/ListMeetingCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/ListMeetingCommandTest.java
@@ -2,8 +2,8 @@
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
import static seedu.address.logic.commands.CommandTestUtil.showMeetingAtIndex;
+import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook;
import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-import static seedu.address.testutil.TypicalMeetings.getTypicalAddressBook;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
diff --git a/src/test/java/seedu/address/logic/commands/MarkMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/MarkMeetingCommandTest.java
new file mode 100644
index 00000000000..2a8e3fd5465
--- /dev/null
+++ b/src/test/java/seedu/address/logic/commands/MarkMeetingCommandTest.java
@@ -0,0 +1,154 @@
+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.showMeetingAtIndex;
+import static seedu.address.logic.parser.ParserUtil.FORMAT;
+import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook;
+import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_MEETING;
+import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
+import static seedu.address.testutil.TypicalIndexes.INDEX_OUT_OF_BOUNDS;
+import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_MEETING;
+
+import java.time.LocalDateTime;
+import java.util.Iterator;
+
+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.meeting.Attendee;
+import seedu.address.model.meeting.Meeting;
+import seedu.address.model.person.Person;
+import seedu.address.testutil.MeetingBuilder;
+import seedu.address.testutil.PersonBuilder;
+
+/**
+ * Contains integration tests (interaction with the Model) and unit tests for
+ * {@code MarkMeetingCommand}.
+ */
+public class MarkMeetingCommandTest {
+
+ private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+
+ @Test
+ public void execute_validIndexUnfilteredList_success() {
+ Meeting meetingToMark = model.getFilteredMeetingList().get(INDEX_FIRST_MEETING.getZeroBased());
+ MarkMeetingCommand markMeetingCommand = new MarkMeetingCommand(INDEX_FIRST_MEETING);
+
+ ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ Meeting markedMeeting = new MeetingBuilder(meetingToMark).withStatus(true).build();
+ String expectedMessage = String.format(MarkMeetingCommand.MESSAGE_MARK_MEETING_SUCCESS,
+ Messages.format(markedMeeting));
+
+ expectedModel.setMeeting(meetingToMark, markedMeeting);
+
+ assertCommandSuccess(markMeetingCommand, model, expectedMessage, expectedModel);
+ }
+
+ @Test
+ public void execute_invalidIndexUnfilteredList_throwsCommandException() {
+ MarkMeetingCommand markMeetingCommand = new MarkMeetingCommand(INDEX_OUT_OF_BOUNDS);
+
+ assertCommandFailure(markMeetingCommand, model, Messages.MESSAGE_INVALID_MEETING_DISPLAYED_INDEX);
+ }
+
+ @Test
+ public void execute_validIndexFilteredList_success() {
+ showMeetingAtIndex(model, INDEX_FIRST_MEETING);
+
+ Meeting meetingToMark = model.getFilteredMeetingList().get(INDEX_FIRST_MEETING.getZeroBased());
+ MarkMeetingCommand markMeetingCommand = new MarkMeetingCommand(INDEX_FIRST_MEETING);
+
+ ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ Meeting markedMeeting = new MeetingBuilder(meetingToMark).withStatus(true).build();
+ expectedModel.setMeeting(meetingToMark, markedMeeting);
+ showMeetingAtIndex(expectedModel, INDEX_FIRST_MEETING);
+ String expectedMessage = String.format(MarkMeetingCommand.MESSAGE_MARK_MEETING_SUCCESS,
+ Messages.format(markedMeeting));
+
+ assertCommandSuccess(markMeetingCommand, model, expectedMessage, expectedModel);
+ }
+
+ @Test
+ public void execute_invalidIndexFilteredList_throwsCommandException() {
+ showMeetingAtIndex(model, INDEX_FIRST_MEETING);
+
+ Index outOfBoundIndex = INDEX_SECOND_MEETING;
+ System.out.println("hi");
+ System.out.println(outOfBoundIndex.getZeroBased());
+ System.out.println(model.getAddressBook().getMeetingList().size());
+ // ensures that outOfBoundIndex is still in bounds of address book list
+ assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getMeetingList().size());
+
+ MarkMeetingCommand markMeetingCommand = new MarkMeetingCommand(outOfBoundIndex);
+
+ assertCommandFailure(markMeetingCommand, model, Messages.MESSAGE_INVALID_MEETING_DISPLAYED_INDEX);
+ }
+
+ @Test
+ public void execute_updatesLastContactedTime_success() {
+ Meeting meetingToMark = model.getFilteredMeetingList().get(INDEX_SECOND_MEETING.getZeroBased());
+ MarkMeetingCommand markMeetingCommand = new MarkMeetingCommand(INDEX_SECOND_MEETING);
+
+ ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ Meeting markedMeeting = new MeetingBuilder(meetingToMark).withStatus(true).build();
+ String expectedMessage = String.format(MarkMeetingCommand.MESSAGE_MARK_MEETING_SUCCESS,
+ Messages.format(markedMeeting));
+
+ expectedModel.setMeeting(meetingToMark, markedMeeting);
+ Iterator attendeeIterator = meetingToMark.getAttendees().iterator();
+ while (attendeeIterator.hasNext()) {
+ Attendee attendee = attendeeIterator.next();
+ Person person = expectedModel.getPerson(attendee.getAttendeeName());
+ Person expectedPerson = new PersonBuilder(person)
+ .withLastContactedTime(meetingToMark.getEnd().format(FORMAT)).build();
+ expectedModel.setPerson(person, expectedPerson);
+ }
+
+ assertCommandSuccess(markMeetingCommand, model, expectedMessage, expectedModel);
+ }
+
+ @Test
+ public void updateLastContactedTime_doesNotUpdateForEarlierTime_success() {
+ Person person = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
+ Person updatedPerson = MarkMeetingCommand.updateLastContactedTime(person, LocalDateTime.MIN);
+ assertEquals(person, updatedPerson);
+ }
+
+ @Test
+ public void equals() {
+ MarkMeetingCommand markFirstCommand = new MarkMeetingCommand(INDEX_FIRST_MEETING);
+ MarkMeetingCommand markSecondCommand = new MarkMeetingCommand(INDEX_SECOND_MEETING);
+
+ // same object -> returns true
+ assertTrue(markFirstCommand.equals(markFirstCommand));
+
+ // same values -> returns true
+ MarkMeetingCommand markFirstCommandCopy = new MarkMeetingCommand(INDEX_FIRST_MEETING);
+ assertTrue(markFirstCommand.equals(markFirstCommandCopy));
+
+ // different types -> returns false
+ assertFalse(markFirstCommand.equals(1));
+
+ // null -> returns false
+ assertFalse(markFirstCommand.equals(null));
+
+ // different meeting -> returns false
+ assertFalse(markFirstCommand.equals(markSecondCommand));
+ }
+
+ @Test
+ public void toStringMethod() {
+ Index targetIndex = Index.fromOneBased(1);
+ MarkMeetingCommand markMeetingCommand = new MarkMeetingCommand(targetIndex);
+ String expected = MarkMeetingCommand.class.getCanonicalName() + "{targetIndex=" + targetIndex + "}";
+ assertEquals(expected, markMeetingCommand.toString());
+ }
+}
diff --git a/src/test/java/seedu/address/logic/commands/RemoveMeetingContactCommandTest.java b/src/test/java/seedu/address/logic/commands/RemoveMeetingContactCommandTest.java
index 5b9e64fd9e7..6ec89228801 100644
--- a/src/test/java/seedu/address/logic/commands/RemoveMeetingContactCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/RemoveMeetingContactCommandTest.java
@@ -5,12 +5,12 @@
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 seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook;
import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_MEETING;
import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
import static seedu.address.testutil.TypicalIndexes.INDEX_OUT_OF_BOUNDS;
import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_MEETING;
import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
import java.util.Arrays;
@@ -23,7 +23,6 @@
import seedu.address.model.meeting.Attendee;
import seedu.address.model.meeting.Meeting;
import seedu.address.testutil.MeetingBuilder;
-import seedu.address.testutil.TypicalMeetings;
import seedu.address.testutil.TypicalPersons;
/**
@@ -36,11 +35,10 @@ public class RemoveMeetingContactCommandTest {
@Test
public void execute_valid_success() {
- model.addMeeting(TypicalMeetings.MEETING1);
- RemoveMeetingContactCommand rmmcCommand = new RemoveMeetingContactCommand(INDEX_FIRST_MEETING,
+ RemoveMeetingContactCommand rmmcCommand = new RemoveMeetingContactCommand(INDEX_SECOND_MEETING,
INDEX_FIRST_PERSON);
- Meeting meeting = model.getFilteredMeetingList().get(INDEX_FIRST_MEETING.getZeroBased());
+ Meeting meeting = model.getFilteredMeetingList().get(INDEX_SECOND_MEETING.getZeroBased());
Attendee attendeeToRemove = meeting.getAttendee(INDEX_FIRST_PERSON);
// No errors thrown
@@ -52,8 +50,8 @@ public void execute_valid_success() {
// Output message is correct
assertEquals(expectedMessage, message);
- Meeting updatedMeeting = model.getFilteredMeetingList().get(INDEX_FIRST_MEETING.getZeroBased());
- String[] expectedAttendees = Arrays.copyOfRange(TypicalPersons.getTypicalAttendees(), 1, 8);
+ Meeting updatedMeeting = model.getFilteredMeetingList().get(INDEX_SECOND_MEETING.getZeroBased());
+ String[] expectedAttendees = Arrays.copyOfRange(TypicalPersons.getTypicalAttendeesSubset1(), 1, 4);
Meeting expectedMeeting = new MeetingBuilder(meeting)
.withAttendees(expectedAttendees)
.build();
@@ -64,7 +62,7 @@ public void execute_valid_success() {
@Test
public void execute_invalidMeetingIndex_throwsCommandException() {
- RemoveMeetingContactCommand rmmcCommand = new RemoveMeetingContactCommand(INDEX_SECOND_MEETING,
+ RemoveMeetingContactCommand rmmcCommand = new RemoveMeetingContactCommand(INDEX_OUT_OF_BOUNDS,
INDEX_FIRST_PERSON);
// throws error for invalid meeting index
@@ -73,7 +71,6 @@ public void execute_invalidMeetingIndex_throwsCommandException() {
@Test
public void execute_invalidAttendeeIndex_throwsCommandException() {
- model.addMeeting(TypicalMeetings.MEETING1);
RemoveMeetingContactCommand rmmcCommand = new RemoveMeetingContactCommand(INDEX_FIRST_MEETING,
INDEX_OUT_OF_BOUNDS);
diff --git a/src/test/java/seedu/address/logic/commands/ViewContactCommandTest.java b/src/test/java/seedu/address/logic/commands/ViewContactCommandTest.java
index 31e855fdf18..c0fb5c2c5ae 100644
--- a/src/test/java/seedu/address/logic/commands/ViewContactCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/ViewContactCommandTest.java
@@ -6,9 +6,9 @@
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.TypicalAddressBook.getTypicalAddressBook;
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;
diff --git a/src/test/java/seedu/address/logic/commands/ViewMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/ViewMeetingCommandTest.java
index fd973f8c579..ac305f4c127 100644
--- a/src/test/java/seedu/address/logic/commands/ViewMeetingCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/ViewMeetingCommandTest.java
@@ -6,9 +6,9 @@
import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
import static seedu.address.logic.commands.CommandTestUtil.showMeetingAtIndex;
+import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook;
import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_MEETING;
import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_MEETING;
-import static seedu.address.testutil.TypicalMeetings.getTypicalAddressBook;
import org.junit.jupiter.api.Test;
@@ -28,21 +28,21 @@ public class ViewMeetingCommandTest {
@Test
public void execute_validIndexUnfilteredList_success() {
- Meeting meetingToView = model.getFilteredMeetingList().get(INDEX_FIRST_MEETING.getZeroBased());
- ViewMeetingCommand viewMeetingCommand = new ViewMeetingCommand(INDEX_FIRST_MEETING);
+ Meeting meetingToView = model.getFilteredMeetingList().get(INDEX_SECOND_MEETING.getZeroBased());
+ ViewMeetingCommand viewMeetingCommand = new ViewMeetingCommand(INDEX_SECOND_MEETING);
String expectedMessage = String.format(Messages.MESSAGE_MEETING_VIEWED_OVERVIEW, meetingToView.getTitle());
- String expectedDisplayString = "Title: CS2103T meeting\n"
+ String expectedDisplayString = "Title: CS2101 meeting\n"
+ "Location: Zoom call url\n"
- + "Start: 20 September 2023, 1000\n"
- + "End: 20 September 2023, 1200\n"
- + "Attendees: [\n1: Alice Pauline \n2: Benson Meier \n3: Carl Kurz \n4: Daniel Meier"
- + " \n5: Elle Meyer \n6: Fiona Kunz \n7: George Best \n8: Hoon Meier]\n";
+ + "Start: 20 November 2023, 1000\n"
+ + "End: 20 November 2023, 1200\n"
+ + "Attendees: [\n1: Daniel Meier \n2: Elle Meyer "
+ + "\n3: Fiona Kunz \n4: George Best]\n";
ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
assertCommandSuccess(viewMeetingCommand, model, expectedMessage, expectedModel);
- assertEquals(meetingToView.toDisplayString(), expectedDisplayString);
+ assertEquals(expectedDisplayString, meetingToView.toDisplayString());
}
@Test
@@ -65,8 +65,7 @@ public void execute_validIndexFilteredList_success() {
+ "Location: Zoom call url\n"
+ "Start: 20 September 2023, 1000\n"
+ "End: 20 September 2023, 1200\n"
- + "Attendees: [\n1: Alice Pauline \n2: Benson Meier \n3: Carl Kurz \n4: Daniel Meier \n5: Elle Meyer"
- + " \n6: Fiona Kunz \n7: George Best \n8: Hoon Meier]\n";
+ + "Attendees: []\n";
// Model displaying filtered list should not change
Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java
index 25f7d61b239..ae25d20165d 100644
--- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java
+++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java
@@ -28,6 +28,7 @@
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.commands.ListMeetingCommand;
+import seedu.address.logic.commands.MarkMeetingCommand;
import seedu.address.logic.commands.RemoveMeetingContactCommand;
import seedu.address.logic.commands.ViewContactCommand;
import seedu.address.logic.commands.ViewMeetingCommand;
@@ -167,6 +168,11 @@ public void parseCommand_rmmc() throws Exception {
RemoveMeetingContactCommand.COMMAND_WORD + " 1 1") instanceof RemoveMeetingContactCommand);
}
+ @Test
+ public void parseCommand_mark() throws Exception {
+ assertTrue(parser.parseCommand(MarkMeetingCommand.COMMAND_WORD + " 1") instanceof MarkMeetingCommand);
+ }
+
@Test
public void parseCommand_unrecognisedInput_throwsParseException() {
assertThrows(ParseException.class, String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE), (
diff --git a/src/test/java/seedu/address/logic/parser/FindMeetingCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindMeetingCommandParserTest.java
index 057e0ee0b78..72037db42e1 100644
--- a/src/test/java/seedu/address/logic/parser/FindMeetingCommandParserTest.java
+++ b/src/test/java/seedu/address/logic/parser/FindMeetingCommandParserTest.java
@@ -80,11 +80,6 @@ public void parse_validArgs_returnsFilterMeetingCommand() {
@Test
public void parse_inValidArgsTime_throwsParseException() {
- LocalDateTime start = LocalDateTime.parse("20.09.2023 1000", FORMAT);
- LocalDateTime end = LocalDateTime.parse("20.09.2023 1200", FORMAT);
- FindMeetingCommand expectedFindMeetingCommand =
- new FindMeetingCommand(preparePredicate(new String[]{"", "", "", ""},
- end, start));
assertParseFailure(parser, " e/20.09.2023 1000 s/20.09.2023 1200",
String.format(MeetingTime.MESSAGE_CONSTRAINTS));
}
diff --git a/src/test/java/seedu/address/logic/parser/MarkMeetingCommandParserTest.java b/src/test/java/seedu/address/logic/parser/MarkMeetingCommandParserTest.java
new file mode 100644
index 00000000000..0b1f192f72b
--- /dev/null
+++ b/src/test/java/seedu/address/logic/parser/MarkMeetingCommandParserTest.java
@@ -0,0 +1,33 @@
+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_MEETING;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.logic.commands.MarkMeetingCommand;
+
+/**
+ * As we are only doing white-box testing, our test cases do not cover path variations
+ * outside of the MarkMeetingCommand code. For example, inputs "1" and "1 abc" take the
+ * same path through the MarkMeetingCommand, 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 MarkMeetingCommandParserTest {
+
+ private MarkMeetingCommandParser parser = new MarkMeetingCommandParser();
+
+ @Test
+ public void parse_validArgs_returnsMarkCommand() {
+ assertParseSuccess(parser, "1", new MarkMeetingCommand(INDEX_FIRST_MEETING));
+ }
+
+ @Test
+ public void parse_invalidArgs_throwsParseException() {
+ assertParseFailure(parser, "a",
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, MarkMeetingCommand.MESSAGE_USAGE));
+ }
+}
diff --git a/src/test/java/seedu/address/model/AddressBookTest.java b/src/test/java/seedu/address/model/AddressBookTest.java
index 475a475b81a..85f3cf950b3 100644
--- a/src/test/java/seedu/address/model/AddressBookTest.java
+++ b/src/test/java/seedu/address/model/AddressBookTest.java
@@ -5,8 +5,8 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook;
import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
import java.util.Arrays;
import java.util.Collection;
@@ -20,6 +20,7 @@
import seedu.address.model.meeting.Meeting;
import seedu.address.model.person.Person;
import seedu.address.model.person.exceptions.DuplicatePersonException;
+import seedu.address.model.person.exceptions.PersonNotFoundException;
import seedu.address.testutil.PersonBuilder;
public class AddressBookTest {
@@ -78,6 +79,17 @@ public void hasPerson_personWithSameIdentityFieldsInAddressBook_returnsTrue() {
assertTrue(addressBook.hasPerson(editedAlice));
}
+ @Test
+ public void getPerson_isInList_success() {
+ addressBook.addPerson(ALICE);
+ assertEquals(ALICE, addressBook.getPerson(ALICE.getName().fullName));
+ }
+
+ @Test
+ public void getPerson_notFound_throwsPersonNotFoundException() {
+ assertThrows(PersonNotFoundException.class, () -> addressBook.getPerson(ALICE.getName().fullName));
+ }
+
@Test
public void getPersonList_modifyList_throwsUnsupportedOperationException() {
assertThrows(UnsupportedOperationException.class, () -> addressBook.getPersonList().remove(0));
diff --git a/src/test/java/seedu/address/model/ModelManagerTest.java b/src/test/java/seedu/address/model/ModelManagerTest.java
index 2cf1418d116..66b41f5e5de 100644
--- a/src/test/java/seedu/address/model/ModelManagerTest.java
+++ b/src/test/java/seedu/address/model/ModelManagerTest.java
@@ -16,6 +16,7 @@
import seedu.address.commons.core.GuiSettings;
import seedu.address.model.person.NameContainsKeywordsPredicate;
+import seedu.address.model.person.exceptions.PersonNotFoundException;
import seedu.address.testutil.AddressBookBuilder;
public class ModelManagerTest {
@@ -88,6 +89,17 @@ public void hasPerson_personInAddressBook_returnsTrue() {
assertTrue(modelManager.hasPerson(ALICE));
}
+ @Test
+ public void getPerson_isInList_success() {
+ modelManager.addPerson(ALICE);
+ assertEquals(ALICE, modelManager.getPerson(ALICE.getName().fullName));
+ }
+
+ @Test
+ public void getPerson_notFound_throwsPersonNotFoundException() {
+ assertThrows(PersonNotFoundException.class, () -> modelManager.getPerson(ALICE.getName().fullName));
+ }
+
@Test
public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException() {
assertThrows(UnsupportedOperationException.class, () -> modelManager.getFilteredPersonList().remove(0));
diff --git a/src/test/java/seedu/address/model/meeting/GeneralMeetingPredicateTest.java b/src/test/java/seedu/address/model/meeting/GeneralMeetingPredicateTest.java
index ff30b765b72..2826781ea7b 100644
--- a/src/test/java/seedu/address/model/meeting/GeneralMeetingPredicateTest.java
+++ b/src/test/java/seedu/address/model/meeting/GeneralMeetingPredicateTest.java
@@ -17,7 +17,6 @@ public class GeneralMeetingPredicateTest {
private LocalDateTime start = LocalDateTime.of(LocalDate.of(0001, 01, 01), LocalTime.of(00, 00));
private LocalDateTime startOn30 = LocalDateTime.of(LocalDate.of(2023, 9, 30), LocalTime.of(10, 00));
private LocalDateTime endOn30 = LocalDateTime.of(LocalDate.of(2023, 9, 30), LocalTime.of(12, 00));
- private LocalDateTime start2 = LocalDateTime.of(LocalDate.of(0001, 01, 02), LocalTime.of(00, 00));
private LocalDateTime end = LocalDateTime.of(LocalDate.of(9999, 12, 31), LocalTime.of(23, 59));
@Test
public void equals() {
diff --git a/src/test/java/seedu/address/model/meeting/MeetingTest.java b/src/test/java/seedu/address/model/meeting/MeetingTest.java
index 533bbe09674..9427d620675 100644
--- a/src/test/java/seedu/address/model/meeting/MeetingTest.java
+++ b/src/test/java/seedu/address/model/meeting/MeetingTest.java
@@ -84,7 +84,8 @@ public void equals() {
public void toStringMethod() {
String expected = Meeting.class.getCanonicalName() + "{title=" + MEETING1.getTitle() + ", location="
+ MEETING1.getLocation() + ", start=" + MEETING1.getStart() + ", end=" + MEETING1.getEnd()
- + ", attendees=" + MEETING1.getAttendees() + ", tags=" + MEETING1.getTags() + "}";
+ + ", attendees=" + MEETING1.getAttendees() + ", tags=" + MEETING1.getTags() + ", status="
+ + MEETING1.getStatus() + "}";
assertEquals(expected, MEETING1.toString());
}
}
diff --git a/src/test/java/seedu/address/model/meeting/MeetingTimeContainsPredicateTest.java b/src/test/java/seedu/address/model/meeting/MeetingTimeContainsPredicateTest.java
index 3dff93d8f21..6fc92c0cb9a 100644
--- a/src/test/java/seedu/address/model/meeting/MeetingTimeContainsPredicateTest.java
+++ b/src/test/java/seedu/address/model/meeting/MeetingTimeContainsPredicateTest.java
@@ -18,7 +18,6 @@ public class MeetingTimeContainsPredicateTest {
private LocalDateTime start = LocalDateTime.of(LocalDate.of(0001, 01, 01), LocalTime.of(00, 00));
private LocalDateTime startOn30 = LocalDateTime.of(LocalDate.of(2023, 9, 30), LocalTime.of(10, 00));
private LocalDateTime endOn30 = LocalDateTime.of(LocalDate.of(2023, 9, 30), LocalTime.of(12, 00));
- private LocalDateTime start2 = LocalDateTime.of(LocalDate.of(0001, 01, 02), LocalTime.of(00, 00));
private LocalDateTime end = LocalDateTime.of(LocalDate.of(9999, 12, 31), LocalTime.of(23, 59));
@Test
diff --git a/src/test/java/seedu/address/model/meeting/StatusTest.java b/src/test/java/seedu/address/model/meeting/StatusTest.java
new file mode 100644
index 00000000000..8ac6743a95a
--- /dev/null
+++ b/src/test/java/seedu/address/model/meeting/StatusTest.java
@@ -0,0 +1,36 @@
+package seedu.address.model.meeting;
+
+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;
+
+public class StatusTest {
+
+ @Test
+ public void constructor() {
+ MeetingStatus status = new MeetingStatus(false);
+ assertEquals(Boolean.FALSE, status.isComplete);
+ }
+
+ @Test
+ public void equals() {
+ MeetingStatus status = new MeetingStatus(false);
+
+ // same values -> returns true
+ assertTrue(status.equals(new MeetingStatus(false)));
+
+ // same object -> returns true
+ assertTrue(status.equals(status));
+
+ // null -> returns false
+ assertFalse(status.equals(null));
+
+ // different types -> returns false
+ assertFalse(status.equals(5.0f));
+
+ // different values -> returns false
+ assertFalse(status.equals(new MeetingStatus(true)));
+ }
+}
diff --git a/src/test/java/seedu/address/model/person/UniquePersonListTest.java b/src/test/java/seedu/address/model/person/UniquePersonListTest.java
index 2ace6c9018f..777ea1265e4 100644
--- a/src/test/java/seedu/address/model/person/UniquePersonListTest.java
+++ b/src/test/java/seedu/address/model/person/UniquePersonListTest.java
@@ -62,6 +62,17 @@ public void add_duplicatePerson_throwsDuplicatePersonException() {
assertThrows(DuplicatePersonException.class, () -> uniquePersonList.add(ALICE));
}
+ @Test
+ public void getPerson_isInList_success() {
+ uniquePersonList.add(ALICE);
+ assertEquals(ALICE, uniquePersonList.getPerson(ALICE.getName().fullName));
+ }
+
+ @Test
+ public void getPerson_notFound_throwsPersonNotFoundException() {
+ assertThrows(PersonNotFoundException.class, () -> uniquePersonList.getPerson(ALICE.getName().fullName));
+ }
+
@Test
public void setPerson_nullTargetPerson_throwsNullPointerException() {
assertThrows(NullPointerException.class, () -> uniquePersonList.setPerson(null, ALICE));
diff --git a/src/test/java/seedu/address/storage/JsonAdaptedMeetingTest.java b/src/test/java/seedu/address/storage/JsonAdaptedMeetingTest.java
index e04d623b48a..e5106d817d9 100644
--- a/src/test/java/seedu/address/storage/JsonAdaptedMeetingTest.java
+++ b/src/test/java/seedu/address/storage/JsonAdaptedMeetingTest.java
@@ -26,11 +26,13 @@ public class JsonAdaptedMeetingTest {
private static final String INVALID_END = "88.88.8888 8888";
private static final String INVALID_ATTENDEE = " ";
private static final String INVALID_TAG = "#friend";
+ private static final String INVALID_STATUS = "untrue";
private static final String VALID_TITLE = MEETING1.getTitle().toString();
private static final String VALID_LOCATION = MEETING1.getLocation().toString();
private static final String VALID_START = MEETING1.getStart().toString();
private static final String VALID_END = MEETING1.getEnd().toString();
+ private static final String VALID_STATUS = MEETING1.getStatus().toString();
private static final Meeting EDITED_MEETING_1 = new MeetingBuilder(MEETING1).withAttendees("Alice Pauline").build();
private static final List VALID_ATTENDEE = EDITED_MEETING_1.getAttendees().stream()
@@ -40,14 +42,14 @@ public class JsonAdaptedMeetingTest {
@Test
public void toModelType_validMeetingDetails_returnsMeeting() throws Exception {
- JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(EDITED_MEETING_1);
- assertEquals(EDITED_MEETING_1, meeting.toModelType());
+ JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(MEETING1);
+ assertEquals(MEETING1, meeting.toModelType());
}
@Test
public void toModelType_invalidTitle_throwsIllegalValueException() throws IllegalValueException {
JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(INVALID_TITLE, VALID_LOCATION, VALID_START, VALID_END,
- VALID_ATTENDEE, VALID_TAGS);
+ VALID_ATTENDEE, VALID_TAGS, "false");
String expectedMessage = Title.MESSAGE_CONSTRAINTS;
assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType);
}
@@ -55,7 +57,7 @@ public void toModelType_invalidTitle_throwsIllegalValueException() throws Illega
@Test
public void toModelType_nullTitle_throwsIllegalValueException() {
JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(null, VALID_LOCATION, VALID_START, VALID_END,
- VALID_ATTENDEE, VALID_TAGS);
+ VALID_ATTENDEE, VALID_TAGS, VALID_STATUS);
String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Title.class.getSimpleName());
assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType);
}
@@ -63,7 +65,7 @@ public void toModelType_nullTitle_throwsIllegalValueException() {
@Test
public void toModelType_invalidLocation_throwsIllegalValueException() {
JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, INVALID_LOCATION, VALID_START, VALID_END,
- VALID_ATTENDEE, VALID_TAGS);
+ VALID_ATTENDEE, VALID_TAGS, VALID_STATUS);
String expectedMessage = Location.MESSAGE_CONSTRAINTS;
assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType);
}
@@ -71,7 +73,7 @@ public void toModelType_invalidLocation_throwsIllegalValueException() {
@Test
public void toModelType_nullLocation_throwsIllegalValueException() {
JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, null, VALID_START, VALID_END, VALID_ATTENDEE,
- VALID_TAGS);
+ VALID_TAGS, VALID_STATUS);
String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Location.class.getSimpleName());
assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType);
}
@@ -79,7 +81,7 @@ public void toModelType_nullLocation_throwsIllegalValueException() {
@Test
public void toModelType_invalidStart_throwsIllegalValueException() {
JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, VALID_LOCATION, INVALID_START, VALID_END,
- VALID_ATTENDEE, VALID_TAGS);
+ VALID_ATTENDEE, VALID_TAGS, VALID_STATUS);
String expectedMessage = MeetingTime.MESSAGE_CONSTRAINTS;
assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType);
}
@@ -87,7 +89,7 @@ public void toModelType_invalidStart_throwsIllegalValueException() {
@Test
public void toModelType_nullStart_throwsIllegalValueException() {
JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, VALID_LOCATION, null, VALID_END,
- VALID_ATTENDEE, VALID_TAGS);
+ VALID_ATTENDEE, VALID_TAGS, VALID_STATUS);
String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, LocalDateTime.class.getSimpleName());
assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType);
}
@@ -95,7 +97,7 @@ public void toModelType_nullStart_throwsIllegalValueException() {
@Test
public void toModelType_invalidEnd_throwsIllegalValueException() {
JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, VALID_LOCATION, VALID_START, INVALID_END,
- VALID_ATTENDEE, VALID_TAGS);
+ VALID_ATTENDEE, VALID_TAGS, VALID_STATUS);
String expectedMessage = MeetingTime.MESSAGE_CONSTRAINTS;
assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType);
}
@@ -103,7 +105,7 @@ public void toModelType_invalidEnd_throwsIllegalValueException() {
@Test
public void toModelType_nullEnd_throwsIllegalValueException() {
JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, VALID_LOCATION, null, VALID_END,
- VALID_ATTENDEE, VALID_TAGS);
+ VALID_ATTENDEE, VALID_TAGS, VALID_STATUS);
String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, LocalDateTime.class.getSimpleName());
assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType);
}
@@ -113,7 +115,7 @@ public void toModelType_invalidAttendees_throwsIllegalValueException() {
List invalidAttendees = new ArrayList<>(VALID_ATTENDEE);
invalidAttendees.add(new JsonAdaptedAttendee(INVALID_ATTENDEE));
JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, VALID_LOCATION, VALID_START, VALID_END,
- invalidAttendees, VALID_TAGS);
+ invalidAttendees, VALID_TAGS, VALID_STATUS);
assertThrows(IllegalValueException.class, meeting::toModelType);
}
@@ -122,7 +124,14 @@ public void toModelType_invalidTags_throwsIllegalValueException() {
List invalidTags = new ArrayList<>(VALID_TAGS);
invalidTags.add(new JsonAdaptedTag(INVALID_TAG));
JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, VALID_LOCATION, VALID_START, VALID_END,
- VALID_ATTENDEE, invalidTags);
+ VALID_ATTENDEE, invalidTags, VALID_STATUS);
+ assertThrows(IllegalValueException.class, meeting::toModelType);
+ }
+
+ @Test
+ public void toModelType_invalidStatus_throwsIllegalValueException() {
+ JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, VALID_LOCATION, VALID_START, VALID_END,
+ VALID_ATTENDEE, VALID_TAGS, INVALID_STATUS);
assertThrows(IllegalValueException.class, meeting::toModelType);
}
diff --git a/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java b/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java
index b074c344bf9..c2442b09e7d 100644
--- a/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java
+++ b/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java
@@ -6,7 +6,7 @@
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 static seedu.address.testutil.TypicalPersons.getTypicalPersonsAddressBook;
import java.io.IOException;
import java.nio.file.Path;
@@ -64,7 +64,7 @@ public void readAddressBook_invalidAndValidPersonAddressBook_throwDataLoadingExc
public void readAndSaveAddressBook_allInOrder_success() throws Exception {
Path filePath = testFolder.resolve("TempAddressBook.json");
- AddressBook original = getTypicalAddressBook();
+ AddressBook original = getTypicalPersonsAddressBook();
JsonAddressBookStorage jsonAddressBookStorage = new JsonAddressBookStorage(filePath);
// Save in new file and read back
diff --git a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java b/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java
index 188c9058d20..adb63e42c81 100644
--- a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java
+++ b/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java
@@ -2,6 +2,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.address.testutil.TypicalPersons.getTypicalPersonsAddressBook;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -11,7 +12,6 @@
import seedu.address.commons.exceptions.IllegalValueException;
import seedu.address.commons.util.JsonUtil;
import seedu.address.model.AddressBook;
-import seedu.address.testutil.TypicalPersons;
public class JsonSerializableAddressBookTest {
@@ -25,7 +25,7 @@ public void toModelType_typicalPersonsFile_success() throws Exception {
JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(TYPICAL_PERSONS_FILE,
JsonSerializableAddressBook.class).get();
AddressBook addressBookFromFile = dataFromFile.toModelType();
- AddressBook typicalPersonsAddressBook = TypicalPersons.getTypicalAddressBook();
+ AddressBook typicalPersonsAddressBook = getTypicalPersonsAddressBook();
assertEquals(addressBookFromFile, typicalPersonsAddressBook);
}
diff --git a/src/test/java/seedu/address/storage/StorageManagerTest.java b/src/test/java/seedu/address/storage/StorageManagerTest.java
index 99a16548970..5457e96ed5a 100644
--- a/src/test/java/seedu/address/storage/StorageManagerTest.java
+++ b/src/test/java/seedu/address/storage/StorageManagerTest.java
@@ -2,7 +2,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook;
import java.nio.file.Path;
diff --git a/src/test/java/seedu/address/testutil/MeetingBuilder.java b/src/test/java/seedu/address/testutil/MeetingBuilder.java
index 4061c053978..86a87fd4242 100644
--- a/src/test/java/seedu/address/testutil/MeetingBuilder.java
+++ b/src/test/java/seedu/address/testutil/MeetingBuilder.java
@@ -10,6 +10,7 @@
import seedu.address.model.meeting.Attendee;
import seedu.address.model.meeting.Location;
import seedu.address.model.meeting.Meeting;
+import seedu.address.model.meeting.MeetingStatus;
import seedu.address.model.meeting.Title;
import seedu.address.model.tag.Tag;
import seedu.address.model.util.SampleDataUtil;
@@ -23,12 +24,15 @@ public class MeetingBuilder {
public static final String DEFAULT_LOCATION = "Room 1";
public static final LocalDateTime DEFAULT_START = LocalDateTime.parse("02.10.2023 1000", FORMAT);
public static final LocalDateTime DEFAULT_END = LocalDateTime.parse("03.10.2023 1000", FORMAT);
+ public static final Boolean DEFAULT_STATUS = false;
+
private Title title;
private Location location;
private LocalDateTime start;
private LocalDateTime end;
private Set attendees;
private Set tags;
+ private MeetingStatus status;
/**
* Creates a {@code MeetingBuilder} with the default details.
@@ -40,6 +44,7 @@ public MeetingBuilder() {
end = DEFAULT_END;
attendees = new LinkedHashSet<>();
tags = new HashSet<>();
+ status = new MeetingStatus(DEFAULT_STATUS);
}
/**
@@ -52,6 +57,7 @@ public MeetingBuilder(Meeting meetingToCopy) {
end = meetingToCopy.getEnd();
attendees = new LinkedHashSet<>(meetingToCopy.getAttendees());
tags = new HashSet<>(meetingToCopy.getTags());
+ status = meetingToCopy.getStatus();
}
/**
@@ -87,7 +93,7 @@ public MeetingBuilder withStart(String start) {
}
/**
- * Sets the {@code start} of the {@code Meeting} that we are building.
+ * Sets the {@code end} of the {@code Meeting} that we are building.
*/
public MeetingBuilder withEnd(String end) {
this.end = LocalDateTime.parse(end, FORMAT);
@@ -95,14 +101,22 @@ public MeetingBuilder withEnd(String end) {
}
/**
- * Sets the {@code Phone} of the {@code Person} that we are building.
+ * Sets the {@code Location} of the {@code Meeting} that we are building.
*/
public MeetingBuilder withLocation(String location) {
this.location = new Location(location);
return this;
}
+ /**
+ * Sets the {@code Status} of the {@code Meeting} that we are building.
+ */
+ public MeetingBuilder withStatus(Boolean status) {
+ this.status = new MeetingStatus(status);
+ return this;
+ }
+
public Meeting build() {
- return new Meeting(title, location, start, end, attendees, tags);
+ return new Meeting(title, location, start, end, attendees, tags, status);
}
}
diff --git a/src/test/java/seedu/address/testutil/TypicalAddressBook.java b/src/test/java/seedu/address/testutil/TypicalAddressBook.java
new file mode 100644
index 00000000000..7d9f3466915
--- /dev/null
+++ b/src/test/java/seedu/address/testutil/TypicalAddressBook.java
@@ -0,0 +1,31 @@
+package seedu.address.testutil;
+
+import seedu.address.model.AddressBook;
+import seedu.address.model.meeting.Meeting;
+import seedu.address.model.person.Person;
+
+/**
+ * A utility class containing a list of {@code AddressBook} objects to be used in
+ * tests.
+ */
+public class TypicalAddressBook {
+ private TypicalAddressBook() {
+ } // prevents instantiation
+
+ /**
+ * Returns an {@code AddressBook} with all the typical persons and meetings.
+ */
+ public static AddressBook getTypicalAddressBook() {
+ AddressBook ab = new AddressBook();
+
+ for (Meeting meeting : TypicalMeetings.getTypicalMeetings()) {
+ ab.addMeeting(meeting);
+ }
+
+ for (Person person : TypicalPersons.getTypicalPersons()) {
+ ab.addPerson(person);
+ }
+
+ return ab;
+ }
+}
diff --git a/src/test/java/seedu/address/testutil/TypicalMeetings.java b/src/test/java/seedu/address/testutil/TypicalMeetings.java
index 67862cb6e71..0b6f9d98242 100644
--- a/src/test/java/seedu/address/testutil/TypicalMeetings.java
+++ b/src/test/java/seedu/address/testutil/TypicalMeetings.java
@@ -4,7 +4,6 @@
import java.util.Arrays;
import java.util.List;
-import seedu.address.model.AddressBook;
import seedu.address.model.meeting.Meeting;
/**
@@ -15,37 +14,30 @@ public class TypicalMeetings {
public static final Meeting MEETING1 = new MeetingBuilder().withTitle("CS2103T meeting")
.withLocation("Zoom call url")
.withStart("20.09.2023 1000").withEnd("20.09.2023 1200")
- .withAttendees(TypicalPersons.getTypicalAttendees())
.withTags("work", "important")
.build();
public static final Meeting MEETING2 = new MeetingBuilder().withTitle("CS2101 meeting")
.withLocation("Zoom call url")
- .withStart("20.09.2023 1000").withEnd("20.09.2023 1200")
- .withAttendees(Arrays.copyOfRange(TypicalPersons.getTypicalAttendees(), 1, 7))
+ .withStart("20.11.2023 1000").withEnd("20.11.2023 1200")
+ .withAttendees(TypicalPersons.getTypicalAttendeesSubset1())
.build();
public static final Meeting MEETING3 = new MeetingBuilder().withTitle("CS2101 meeting")
.withLocation("com 3")
- .withStart("20.09.2023 1000").withEnd("20.09.2023 1200")
- .withAttendees(TypicalPersons.getTypicalAttendees())
+ .withStart("20.11.2023 1000").withEnd("20.11.2023 1200")
+ .withAttendees(TypicalPersons.getTypicalAttendeesSubset2())
.build();
public static final Meeting MEETING4 = new MeetingBuilder().withTitle("ABCDE meeting")
.withLocation("com 3")
- .withStart("30.09.2023 1000").withEnd("30.09.2023 1200")
- .withAttendees(TypicalPersons.getTypicalAttendees())
+ .withStart("30.11.2023 1000").withEnd("30.11.2023 1200")
+ .withAttendees(TypicalPersons.getTypicalAttendeesAll())
.withTags("work", "important")
.build();
- public static AddressBook getTypicalAddressBook() {
- AddressBook ab = new AddressBook();
- for (Meeting meeting : getTypicalMeetings()) {
- ab.addMeeting(meeting);
- }
-
- return ab;
- }
+ private TypicalMeetings() {
+ } // prevents instantiation
public static List getTypicalMeetings() {
return new ArrayList<>(Arrays.asList(MEETING1, MEETING2, MEETING3, MEETING4));
diff --git a/src/test/java/seedu/address/testutil/TypicalPersons.java b/src/test/java/seedu/address/testutil/TypicalPersons.java
index 60d28dc1240..d14996cee91 100644
--- a/src/test/java/seedu/address/testutil/TypicalPersons.java
+++ b/src/test/java/seedu/address/testutil/TypicalPersons.java
@@ -63,26 +63,35 @@ public class TypicalPersons {
private TypicalPersons() {
} // prevents instantiation
+ public static List getTypicalPersons() {
+ return new ArrayList<>(Arrays.asList(ALICE, BENSON, CARL, DANIEL, ELLE, FIONA, GEORGE, HOON));
+ }
+
/**
- * Returns an {@code AddressBook} with all the typical persons and meetings.
+ * Returns an {@code AddressBook} with all the typical persons only.
*/
- public static AddressBook getTypicalAddressBook() {
+ public static AddressBook getTypicalPersonsAddressBook() {
AddressBook ab = new AddressBook();
- for (Person person : getTypicalPersons()) {
+
+ for (Person person : TypicalPersons.getTypicalPersons()) {
ab.addPerson(person);
}
return ab;
}
- public static List getTypicalPersons() {
- return new ArrayList<>(Arrays.asList(ALICE, BENSON, CARL, DANIEL, ELLE, FIONA, GEORGE, HOON));
- }
-
- public static String[] getTypicalAttendees() {
+ public static String[] getTypicalAttendeesAll() {
List typicalPersons = getTypicalPersons();
String[] typicalAttendees = typicalPersons.stream().map(Person::getName).map(Name::toString)
- .collect(Collectors.toList()).toArray(new String[0]);
+ .collect(Collectors.toList()).toArray(String[]::new);
return typicalAttendees;
}
+
+ public static String[] getTypicalAttendeesSubset1() {
+ return Arrays.copyOfRange(getTypicalAttendeesAll(), 3, 7);
+ }
+
+ public static String[] getTypicalAttendeesSubset2() {
+ return Arrays.copyOfRange(getTypicalAttendeesAll(), 1, 4);
+ }
}