Developer Guide
- Acknowledgements
- Setting up, getting started
- Design
- Implementation
- Documentation, logging, testing, configuration, dev-ops
- Appendix: Requirements
- Appendix: Planned Enhancement
-
Appendix: Instructions for manual testing
- Launch and shutdown
- Viewing help
- Clearing all the data
- Exiting the program
- Adding an applicant
- Deleting an applicant
- Editing an applicant
- Finding applicants from the list
- Listing all applicants
- Adding an interview
- Deleting an interview
- Editing an interview
- Finding interviews from the list
- Listing all interviews
- Listing all free timing for the given day
- Listing all interviews for today
- Marking an interview as done
- Rating an interview
- Listing all completed interview
- Listing all incomplete interview
- Sorting the interview list by rating
- Sorting the interview list by start-time
Acknowledgements
- The foundational code for add, find and Interview’s CRUD features are adapted from AB-3.
- The formatting for the developer guide is inspired by NUSCoursemates.
- The formatting for the developer guide is inspired by InTrack.
Setting up, getting started
Refer to the guide Setting up and getting started.
Design
.puml
files used to create diagrams in this document can be found in the
docs/diagrams
folder. Refer to the PlantUML Tutorial at se-edu/guides to learn how to create and edit diagrams.
Architecture
The Architecture Diagram given above explains the high-level design of the App.
Given below is a quick overview of main components and how they interact with each other.
Main components of the architecture
Main
(consisting of classes Main
and MainApp
) is in charge of the app launch and shut down.
- At app launch, it initializes the other components in the correct sequence, and connects them up with each other.
- At shut down, it shuts down the other components and invokes cleanup methods where necessary.
The bulk of the app’s work is done by the following four components:
-
UI
: The UI of the App. -
Logic
: The command executor. -
Model
: Holds the data of the App in memory. -
Storage
: Reads data from, and writes data to, the hard disk.
Commons
represents a collection of classes used by multiple components above.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete-a 1
.
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 APIinterface
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 components being coupled to the implementation of a component), as illustrated in the (partial) class diagram below.
The sections below give more details of each component.
UI component
The API of this component is specified in Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, ApplicantListPanel
, StatusBarFooter
etc. All these, including the MainWindow
, inherit from the abstract UiPart
class which captures the commonalities between classes that represent parts of the visible GUI.
The UI
component uses the JavaFx UI framework. The layout of these UI parts are defined in matching .fxml
files that are in the src/main/resources/view
folder. For example, the layout of the MainWindow
is specified in MainWindow.fxml
The UI
component,
- executes user commands using the
Logic
component. - listens for changes to
Model
data so that the UI can be updated with the modified data. - keeps a reference to the
Logic
component, because theUI
relies on theLogic
to execute commands. - depends on some classes in the
Model
component, as it displaysApplicant
object residing in theModel
.
Logic component
API : Logic.java
Here’s a (partial) class diagram of the Logic
component:
The sequence diagram below illustrates the interactions within the Logic
component, taking execute("delete-a 1")
API call as an example.
DeleteCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
How the Logic
component works:
- When
Logic
is called upon to execute a command, it is passed to anAddressBookParser
object which in turn creates a parser that matches the command (e.g.,DeleteCommandParser
) and uses it to parse the command. - This results in a
Command
object (more precisely, an object of one of its subclasses e.g.,DeleteCommand
) which is executed by theLogicManager
. - The command can communicate with the
Model
when it is executed (e.g. to delete an applicant). - The result of the command execution is encapsulated as a
CommandResult
object which is returned back fromLogic
.
Here are the other classes in Logic
(omitted from the class diagram above) that are used for parsing a user command:
How the parsing works:
- When called upon to parse a user command, the
AddressBookParser
class creates anXYZCommandParser
(XYZ
is a placeholder for the specific command name e.g.,AddCommandParser
) which uses the other classes shown above to parse the user command and create aXYZCommand
object (e.g.,AddCommand
) which theAddressBookParser
returns back as aCommand
object. - All
XYZCommandParser
classes (e.g.,AddCommandParser
,DeleteCommandParser
, …) inherit from theParser
interface so that they can be treated similarly where possible e.g, during testing.
Model component
API : Model.java
The Model
component,
- stores the address book data i.e., all
Applicant
objects (which are contained in aUniqueApplicantList
object) as well as allInterview
objects (which are contained in aUniqueInterviewList
object). - stores the currently ‘selected’
Applicant
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<Applicant>
that can be ‘observed’ e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. - stores a
UserPref
object that represents the user’s preferences. This is exposed to the outside as aReadOnlyUserPref
objects. - does not depend on any of the other three components (as the
Model
represents data entities of the domain, they should make sense on their own without depending on other components)
Tag
list in the AddressBook
, which Applicant
references. This allows AddressBook
to only require one Tag
object per unique tag, instead of each Applicant
needing their own Tag
objects.Storage component
API : Storage.java
The Storage
component,
- can save both address book data and user preference data in JSON format, and read them back into corresponding objects.
- inherits from both
AddressBookStorage
andUserPrefStorage
, which means it can be treated as either one (if only the functionality of only one is needed). - depends on some classes in the
Model
component (because theStorage
component’s job is to save/retrieve objects that belong to theModel
)
Common classes
Classes used by multiple components are in the seedu.address.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Add interview feature
The add interview feature allows users to quickly add a scheduled interview into the application via the command
add-i app/APPLICANT_INDEX jr/JOB_ROLE start/START_DATE_AND_TIME end/END_DATE_AND_TIME
Implementation
The add-i
command is facilitated by the AddInterviewCommand
and the AddInterviewCommandParser
.
It uses ArgumentTokenizer#tokenize(String argString, Prefix... prefixes)
to extract the corresponding inputs for each field defined.
The Applicant is then obtained from the model using Model#getFilteredApplicantList()
to get the Applicant List,
followed by List#get(int index)
where the index is the provided Applicant Index.
A new Interview
object is then created with the obtained applicant, the inputted job role, start time and end time.
By default, the rating field will be set to 0.0
and the isDone field set to false
.
Model#setApplicant(Applicant target, Applicant editedApplicant)
is then called to update the target applicant’s hasInterview
status to true
.
Model#addInterview(Interview interview)
is then called to add the new Interview
object into the list of interviews.
How is the command executed
- The user inputs the
add-i
command with correct parameters provided - The
AddressBookParser
processes the input and creates a newAddInterviewCommandParser
. - The
AddInterviewCommandParser
then extracts the relevant inputs for each prefix. If any of the compulsory prefixes have an absent or invalid input, a ParseException will be thrown. - The
AddInterviewCommandParser
then creates theAddInterviewCommand
based on the processed input. - The
LogicManager
executes theAddInterviewCommand
. - The
AddInterviewCommand
then creates a newInterview
object with the corresponding parsed inputs for each field. - The
AddInterviewCommand
then callsModel#setApplicant(Applicant target, Applicant editedApplicant)
to update the Applicant in the Applicant list - The
AddInterviewCommand
then callsModel#addInterview(Interview interview)
to add the newInterview
object to the list of interviews. - Finally, the
AddInterviewCommand
creates aCommandResult
with the success message and returns it to theLogicManager
to complete the command execution. The GUI would then be updated to display the updated lists and success message.
For easier of viewing, 2 sequence diagrams will be used to show how the add-i
command works.
Step 1 to 4:
The activation bar of LogicManager
is intended to not end since it continues being in the activated state for the steps that follow.
Step 5 to 9:
Find interview by job role feature
Implementation
The find interview by job role feature allows users to query the list of added interview for interviews that match the job role via the command find-i KEYWORD(S)
, where KEYWORD(S)
must not
be an empty string.
The find-i
command is facilitated by the FindInterviewCommand
, FindInterviewCommandParser
, and JobContainsKeywordsPredicate
.
It uses Model#updateFilteredInterviewList(Predicate<Interview> predicate)
to apply the JobContainsKeywordsPredicate
in order to produce a filtered list containing only entries whose job correspond to KEYWORD(S)
.
How is the command executed
- The user inputs the
find-i
command together with non-empty job role as keyword(s); - The
LogicManager
receives the command string and forwarded it to theAddressBookParser
. - The
AddressBookParser
checks the type of command and constructsFindInterviewCommandParser
to parse the keyword(s). - The
FindInterviewCommandParser
constructsJobContainsKeywordsPredicate
containing the keyword as predicate. - The
LogicManager
executes theFindInterviewCommand
which calls theModel#updateFilteredInterviewList(Predicate<Interview> predicate)
method. - The
FindInterviewCommand
constructCommandResult
containing the number of successful interviews filtered in the final list and returns it toLogicManager
. - The GUI will be updated automatically when the list changes.
The following sequence diagram shows how the find-i
operation works:
The following activity diagram summarizes what happens when a user executes a new command:
Design Consideration
Aspect: Case-sensitivity in search:
-
Alternative 1 (current choice): Case-insensitive search.
- Pros:
- Offers flexibility and speed up the input process without worrying on casing.
- Cons:
- A less accurate filters as it will return any matched keyword regardless of casing which might not be intended by the user.
- Pros:
-
Alternative 2: Case-sensitive search.
- Pros:
- A more precise filtering as the string is exact match
- Cons:
- Less flexible as the users need to be precise with the input.
- Pros:
Aspect: Accept multiple keywords:
-
Alternative 1 (current choice): Accept multiple keywords.
- Pros:
- Offers a stronger filter to search the interview easily.
- Cons:
- Requires more care to parse the input correctly in order to not miss any keywords.
- Pros:
-
Alternative 2: Accept one keyword.
- Pros:
- Easier to control the input and filtering.
- Cons:
- Less powerful since users can only search job based on one keyword.
- Pros:
Find applicant feature
Implementation
The find applicant feature allows users to query the list of applicants for applicants whose name, phone, email, address and tags match the given arguments.
This can be done
via the command find-a [n/KEYWORD(S)] [p/NUMBER]
[e/KEYWORD(S)] [a/KEYWORD(S)] [t/KEYWORD(S)]
.
The find applicant feature is facilitated by FindApplicantCommand
, FindApplicantCommandParser
,
AddressContainsKeywordsPredicate
, EmailContainsKeywordsPredicate
, NameContainsKeywordsPredicate
,
PhoneContainsNumberPredicate
, TagContainsKeywordsPredicate
and ApplicantPredicate
.
It uses Model#updateFilteredApplicantList(Predicate<Applicant>)
to apply the predicates
in order to produce a filtered list containing only the filtered entries.
How is the command executed
- The user inputs the
find-a
command together with arguments. - The
LogicManager
receives The LogicManager receives the command string and forwards it to the AddressBookParser. - The
AddressBookParser
checks the type of command and constructsFindCommandParser
to parse the arguments. - If the arguments contain the
n/
prefix, aNameContainsKeywordsPredicate
is created with the keywords. - If the arguments contain the
p/
prefix, aPhoneContainsNumberPredicate
is created with the number. - If the arguments contain the
e/
prefix, aEmailContainsKeywordsPredicate
is created with the keywords. - If the arguments contain the
a/
prefix, aAddressContainsKeywordsPredicate
is created with the keywords. - If the arguments contain the
t/
prefix, aTagContainsKeywordsPredicate
is created with the keywords. - An
ApplicantPredicate
is created with all the predicates created above. - The
FindCommandParser
constructs theFindCommand
with theApplicantPredicate
and returns it toLogicManager
. - The
LogicManager
executes theFindCommand
which calls theModel#updateFilteredApplicantList(Predicate<Interview> predicate)
method. - The
FindCommand
constructs aCommandResult
containing the number of applicants found and the success message. -
FindCommand
returns theCommandResult
to LogicManager. - The GUI updates automatically when the list changes.
The following sequence diagram shows how the find-a
operation works:
The following activity diagram summarizes what happens when a user executes a new command:
Design Considerations
Aspect: How find applicant command filters applicants:
-
Alternative 1 (current choice): Use a predicate for each field
- Pros:
- Decrease coupling and increases extensibility.
- Easier to maintain
- Cons:
- More difficult and tedious to implement
- More test cases needed for each predicate
- Pros:
-
Alternative 2: Use one predicate for the entire applicant
- Pros:
- Easier to code and less code to write
- Cons:
- Harder to maintain
- More coupling as predicates for different fields are not abstracted out
- Pros:
Aspect: Which find command format
-
Alternative 1 (current choice): Accepts multiple space or comma separated keywords for each prefix
- Pros:
- Allows filtering using multiple keywords in a single find command
- User can type the command quickly
- Cons:
- Only allows filtering by words and not phrases
- Pros:
-
Alternative 2: Accepts one keyword for each prefix
- Pros:
- Easy to implement
- User can type the command quickly
- Cons:
- Can only find using one keyword for each applicant field in a single find command
- Pros:
-
Alternative 3: Accepts duplicate prefixes and a keyphrase for each prefix
- Pros:
- Allows filtering of multiple keywords or keyphrase in a single find command
- The most specific filter out of all the alternatives
- Cons:
- Most difficult to implement of all alternatives considered
- The command can be slow to type due to the need to type many prefixes
- Pros:
Aspect: How find command matches the arguments for name
-
Alternative 1 (current choice): Match keywords to words in the name
- Pros:
- Can find a person with only the first name or last name
- Cons:
- Less specific than exact matching
- Pros:
-
Alternative 2: Require exact match between arguments and name
- Pros:
- More specific search
- Cons:
- Users need to type longer commands to search for an applicant
- Less flexibility
- Pros:
-
Alternative 3: Check if argument is substring of the name
- Pros:
- Users can find an applicant without typing an entire word
- More flexibility
- Cons:
- Too many applicants might show up in a single find command which defeats the purpose of the find command
- Pros:
parseDate API
Implementation
This feature is implemented though the TimeParser
class. This class contains several public static methods related to manipulating time:
-
TimeParser#parseDate(String date, boolean dateOnly)
— Takes in a time String as input, and returns aTime
instance, which is a wrapper class for a LocalDateTime object which will store the time information (i.e. day, month, year, hour, minute) as well as providing utility methods for manipulating Time.- The
dateOnly
parameter is a flag to indicate how to parse the givendate
. IfdateOnly
is set to false, then the TimeParser will parse valid dates that are in the list of accepted date (without time) formats. Otherwise, ifdateOnly
is set to true, then the TimeParser will parse valid dates that are in the list of accepted date (with time) formats. - Accepted time formats:
- DD/MM/YYYY and time:
16 May 2024 TIME
16-05-2024 TIME
16-05-24 TIME
16/05/2024 TIME
16/05/24 TIME
- MM, DD and time:
16 May TIME
16 January TIME
16/5 TIME
16/05 TIME
- The
TIME
placeholder can be replaced with the formats below:1515
3.15pm
3pm
- DD/MM/YYYY and time:
- Accepted date formats
- DD/MM/YYYY:
16-05-2024
16/05/2024
- DD/MM:
16/05
-
16 May
- Must be a prefix of a valid month of at least 3 characters
- DD/MM/YYYY:
- The Sequence Diagram below illustrates how other classes interact with
TimeParser
whenparseDate(date, false)
is called.
- The
How is the command executed
- The caller passes in the
date
string, which contains the date information. The caller also passes in the boolean flagdateOnly
, which will indicate whether the string should be parsed into aTime
instance containing date and time, or strictly date only. - If the parsing was successful, a
Time
instance containing the Time info will be returned.
Design considerations
Aspect: How TimeParser#parseDate(String date, boolean dateOnly)
works:
-
Alternative 1 (current choice): Have two hardcoded list of acceptable time formats. One with date and time, the other for time
- Pros:
- Easy to implement
- Avoids code duplication
- Cons:
- May have performance issues in terms of time (i.e. might have to loop through the whole list to find a suitable format)
- Huge number of time formats available, hence there is a need to update the list of acceptable time formats in future iterations
- Many errors possible due to the many time fields that the user could format wrongly, which makes implementation difficult
- Using the same method to parse strings with date & time and strings with date only might be prone to bugs
- Pros:
-
Alternative 2 : Have two hardcoded list of acceptable time formats. One with date and time, the other for time, but parse the two types of time string (i.e. strings with date & time, and strings with date only separately)
- Pros:
- Easy to implement
- Less prone to bugs since there are now separate methods for parsing the two types of strings
- Cons:
- Causes code duplication since the algorithm is virtually the same for both
parseDate
methods - Not an optimal implementation (i.e. might have to loop through the whole list to find a suitable format)
- Huge number of time formats available, hence there is a need to update the list of acceptable time formats in future iterations if needed
- Many errors possible due to the many time fields that the user could format wrongly, which makes implementation difficult
- Causes code duplication since the algorithm is virtually the same for both
- Pros:
-
Alternative 3 (alternate choice): Use other time libraries
- Pros:
- Might be a better alternative to alternative 1
- Error checking already implemented
- Cons:
- Will have to overhaul the entire TimeParser class, which might be impractical
- High risk; not guaranteed to be better after overhaul
- Developer is not familiar with other time libraries
- Pros:
List all free timing for a given day feature
Implementation
The list free times for a given day feature allows the user to list all the blocks of time that are not taken by a scheduled interview. This command is in the format list-freetime DATE
where DATE
is a valid date string.
The Sequence Diagram below illustrates the interactions within the Logic
component when execute("list-freetime 12/12/2099")
is called.
The list-freetime DATE
command is facilitated by the ListFreeTimeCommand
, ListFreeTimeCommandParser
, along with the other internal classes omitted for brevity.
How is the command executed
- The user inputs the
list-freetime DATE
command. - The
LogicManager
receives the command string and forwards it to theAddressBookParser
. - The
AddressBookParser
checks the type of command and constructsListFreeTimeCommandParser
to parse the keyword(s). - The
execute
method of theListFreeTimeCommandParser
is called, which will call theparseDate
method of theTimeParser
API class. -
parseDate
will take in the date string as argument. If valid, it will return aTime
instance containing a LocalDateTime containing the date information. - The
ListFreeTimeCommandParser
constructsListFreeTimeCommand
with the Time instance (created byparseDate
earlier) passed into its constructor. - The
LogicManager
executes theListFreeTimeCommand
which calls theModel#listPocketsOfTimeOnGivenDay(Time givenDay)
method. - The
ListFreeTimeCommand
will then use an internal method, formatFreeTime(List<Pair<Time, Time» freeTimes), to parse the list of free times into a string. - The
ListFreeTimeCommand
constructCommandResult
containing the free times on the given day, and returns it toLogicManager
. - The GUI will be updated automatically by when the list changes.
Design considerations
Aspect: How the command finds free times:
-
Alternative 1 (current choice): implement a method in the
ModelManager
class- Pros:
- Can access all the interviews that the user has scheduled that is within the
AddressBook
object instance, which maintains the information hiding principle
- Can access all the interviews that the user has scheduled that is within the
- Cons:
- The command will cause the control to be passed to
ModelManager
first, then toAddressBook
where the logic for looking for free times happens. This results in an additional layer of abstraction, which increases the complexity of the command slightly
- The command will cause the control to be passed to
- Pros:
-
Alternative 2: Use the getter methods of the
AddressBook
class- Pros:
- One less layer of abstraction, reducing complexity
- Easier to implement
- Cons:
- The
ListFreeTimeCommand
will have to call thegetAddressBook
method of theModelManager
object instance, and then use the getter method of theAddressBook
object instance. Violates the Law of Demeter principle since the methods of a stranger (i.e.AddressBook
) is being called, whichListFreeTimeCommand
is not closely related to - Increases coupling since
ListFreeTimeCommand
now has a dependency withAddressBook
- The
- Pros:
List all interviews for today feature
Implementation
The list all interviews today feature allows users to list all the interviews that are scheduled on the day the user executes the command.
How is the command executed
- The user inputs the
list-i-today
command. - The
LogicManager
receives the command string and forwards it toAddressBookParser
. - The
AddressBookParser
checks the type of command and constructs aListInterviewsTodayCommand
instance. -
AddressBookParser
returns theListInterviewsToday
instance toLogicManager
. - The
LogicManager
executes theListInterviewsToday
command. - The execute method in
ListInterviewsToday
calls theModel#updateFilteredInterviewList(Predicate<Interview> predicate)
method and passes in a predicate which tests if an interview is scheduled for today. -
ListInterviewsToday
constructs aCommandResult
containing the success message and returns itLogicManager
. - The GUI updates automatically when the list changes.
The following sequence shows how the list-i-today
command works:
Design considerations
Aspect: Command format
-
Alternative 1 (current choice):
list-i-today
- Pros:
- Easy and fast to type
- Easy to implement
- Cons:
- Can only list interviews today
- Need to type a few hyphens which can be less intuitive than space
- Pros:
-
Alternative 2:
list-i DATE
- Pros:
- Can list interviews on any date
- More flexible
- Cons:
- Can be annoying to type exact date
- Listing interviews today requires the user to know the date today
- Harder to implement
- Pros:
-
Alternative 3:
list-i today
- Pros:
- Some users may prefer typing spaces instead of hyphens
- Cons:
- Harder to implement as the parser needs to differentiate between
list-i
andlist-i today
- Some users may prefer the hyphen instead of a space
- Harder to implement as the parser needs to differentiate between
- Pros:
List interviews done/not done feature
Implementation
The list interviews done/not done feature allows the user to see all the interviews that are done or not done in a single command. The command format is list-i-done
to show all the interviews that are done, and list-i-not-done
to show all interviews that are not done.
The Sequence Diagram below illustrates the interactions within the Logic
component when execute("list-i-done")
is called.
How is the command executed
- The user inputs
list-i-done
orlist-i-not-done
- The
LogicManager
receives the command string and forwards it to theAddressBookParser
. - The
AddressBookParser
checks the type of command and returns aListInterviewsDoneCommand
instance orListInterviewsNotDoneCommand
instance - The
LogicManager
executes theListInterviewsDoneCommand
orListInterviewsNotDoneCommand
- The
execute
method ofListInterviewsDoneCommand
orListInterviewsNotDoneCommand
will callModel#updateFilteredInterviewList(Predicate<Interview> predicate)
, where anInterviewIsDonePredicate
orInterviewNotDonePredicate
is passed as the argument -
Model#updateFilteredInterviewList
will be called with the given predicate, thus updating the internalFilteredList
of interviews to show only those that are done, or those that are not done. TheCommandResult
containing the success message will be returned toLogicManager
. - The GUI will be updated automatically by when the list changes.
Design considerations
Aspect: How the command is implemented
-
Alternative 1 (current choice): Use the existing open-closed principle of AB3 to add these new commands
- Pros:
- Reduces this to a problem that AB3 has already solved
- Maintains consistency with the AB3 format
- Consequently, it is easy to implement
- Cons:
- More command classes have to be added, which can increase coupling
- Pros:
Rate interview feature
Implementation
the rate feature allows users to assign a rating value to the specified interview via the command rate INTERVIEW_INDEX RATING
, where INTERVIEW_INDEX
must be a positive unsigned integer within the list and RATING
must be a positive unsigned one decimal place number between 0.0 to 5.0 inclusive.
The rate
feature is facilitated by the Rating
class, RateCommand
and the RateCommandParser
. The RateCommandParser
utilises the ParseUtil#parseIndex
and ParseUtil#parseRating
to check the validity of the arguments given. Once the validity of the input is confirmed, the Model#setInterview
will update the rating by replacing the old interview with the new interview that has the updated RATING
.
How is the command executed
- The user inputs the
rate
command together with the valid parameters. - The
LogicManager
receives the command string and forwards it to theAddressBookParser
. - The
AddressBookParser
checks the type of command and constructsRateCommandParser
to parse the parameters. - The
RateCommandParser
will pass theINTERVIEW_INDEX
andRATING
to theParseUtil
to check for validity and createsRateCommand
. - The
LogicManager
executes theRateCommand
which calls theModel#getFilteredInterviewList
to get the size of the current list to ensure theINTERVIEW_INDEX
is within the interview list size. - The
Model#setInterview
method will be called next inRateCommand
to update the new interview with the new rating. - The
RateCommand
constructsCommandResult
to return the success message to be displayed by the GUI.
The following sequence diagram shows how the rate
operation works:
The following activity diagram summarizes what happens when a user executes a new command:
Design considerations
-
Alternative 1 (current choice): Stricter rating value with specific format
- Pros:
- Offer simplicity in terms of usage as the users does not have to come out with a rating system.
- Cons:
- Less flexibility as the users are restricted to rate it within the valid range and format
- Pros:
-
Alternative 2: Allow any rating value with no format restriction
- Pros:
- Allow greater flexibility as the users can decide what is a good range for themselves.
- Cons:
- The users’ responsibility is higher to ensure the rating system is suitable for ranking applicants.
- Pros:
Sort interview feature
Implementation
The sort interview feature allows the user to sort all the interviews that have scheduled via the commands sort-SORT_PARAMETER
, where SORT_PARAMETER
can either be rate
or time
.
The sort
command is facilitated by the SortRateCommand
and the SortTimeCommand
. It enables the user to sort all the scheduled interviews by rating or timing. For rating, the interviews will be sorted in descending order of rating. For interview times, the interviews will be sorted in ascending chronological order of start time.
The Sequence Diagram below illustrates the interactions within the Logic
component when execute("sort-rate")
is called.
How is the command executed
- The user inputs the
sort-rate
orsort-time
command - The
LogicManager
receives thesort-rate
orsort-time
command string and forwards it to theAddressBookParser
. - The
AddressBookParser
checks the type of command and returns eitherSortRateCommand
orSortTimeCommand
. - The
LogicManager
executes theSortRateCommand
orSortTimeCommand
which calls theModel#sortInterviewList(Comparator<Interview> comparator)
method. - The
SortRateCommand
orSortTimeCommand
has their ownComparator
object instance. Their respective comparators will be passed into theModel#sortInterviewList(Comparator<Interview> comparator)
-
Model#sortInterviewList(Comparator<Interview> comparator)
will then call theAddressBook#sortInterview(Comparator<Interview> comparator)
, passing in the given comparator as argument. -
Model#sortInterviewList(Comparator<Interview> comparator)
will call theUniqueInterviewList#sort(Comparator<Interview> comparator)
, which will call the built-inFXCollections#sort(Comparator<T> comparator)
method, which will then sort the internal list of interviews by either rating or timing. Note thatFXCollections#sort(Comparator<T> comparator)
is used since the list of interviews is implemented as anObservableList
- The GUI will be updated automatically by when the list changes.
Design considerations
Aspect: How the sort command works
-
Alternative 1 (current choice): Implement the sort method in the
ModelManager
,AddressBook
, and theUniqueInterviewList
class- Pros:
- Does not violate the Law of Demeter principle, since the sort is called through
Model
in theSortRateCommand
orSortTimeCommand
, where theModel
instance is passed as a parameter to the respectiveexecute
commands - Does not violate the information hiding principle. This is because the internal list of interviews is never accessed nor modified directly by the
execute
command of the respective command objects
- Does not violate the Law of Demeter principle, since the sort is called through
- Cons:
- The command will cause the control to be passed to
ModelManager
first, then toAddressBook
and then finally toUniqueInterviewList
where only inUniqueInterviewList
is the internal list sorted. This results in an additional layer of abstraction, which increases the complexity of the command slightly
- The command will cause the control to be passed to
- Pros:
Documentation, logging, testing, configuration, dev-ops
Appendix: Requirements
Product scope
Target user profile:
- is a hiring manager working in Technology/Engineering field
- has a need to manage a significant number of job applicants and interviews
- prefer desktop apps over other types
- can type fast
- prefers typing to mouse interactions
- is reasonably comfortable using CLI apps
Value proposition:
- Manage applicants and interviews faster than a typical mouse/GUI driven contact.
- Easy viewing of top applicants.
- Easy scheduling of interviews without time clash.
User stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
New user of the app | see usage instructions | refer to instructions when I first started to use the App |
* * * |
Engineering Hiring Manager ready for job applicant | add a new applicant | save their contact details into the App |
* * * |
Engineering Hiring Manager with many applicants | rate an applicant | keep track of the applicant performance for the interview |
* * * |
Engineering Hiring Manager ready to start an interview | schedule an interview | save the interview information into the application |
* * * |
Engineering Hiring Manager ready for next round of interview | delete an applicant | remove their contact details that I no longer need |
* * * |
Engineering Hiring Manager that finished an interview | delete an interview | remove the interview that has already been completed |
* * * |
Busy Engineering Hiring Manager | find an applicant by name | locate details of applicants without having to go through the entire list |
* * * |
Busy Engineering Hiring Manager | find a interview by job role | easily locate the interview for the particular job role |
* * |
Busy Engineering Hiring Manager | set reminder of interview | stay organised and track upcoming interview |
* * |
Engineering Hiring Manager with sensitive information | hide private contact details | protect the privacy of the applicants information in the App |
* * |
Engineering Hiring Manager with many applicants | sort the applicants by skill | prioritise and focus on the most promising candidates |
* * |
Busy Engineering Hiring Manager | find free time slot | schedule an interview without time clash |
* * |
Engineering Hiring Manager | update an applicant details | easily update their information on the App |
* * |
Engineering Hiring Manager | update a job role | easily change the details about the job role |
* * |
Engineering Hiring Manager with limited budget | track the cost per hire | ensure that the company budget is not exceeded |
* * |
Team-Oriented Engineering Hiring Manager | add other interviewer | facilitate collaboration and delegation of responsibilities |
* |
Organised Engineering Hiring Manager | sort applicants by name | locate an applicant easily |
* |
Engineering Hiring Manager with many contacts | import contacts from other file | add multiple contacts into the App smoothly |
* |
Meticulous Engineering Hiring Manager | store the applicant’s background | make a more informed choice to benefit the company |
* |
Engineering Hiring Manager with multiple rounds of interview | track the progress of each candidate | maintain a clear overview of our recruitment efforts |
* |
New Engineering Hiring Manager | analyse the performance of the interview | make improvements to my interview processes |
* |
Helpful Engineering Hiring Manager | provide feedback to the applicant | offer constructive advice to help them improve their skills |
* |
Long user of the app | provide feedback to the developer | suggest improvements and enhancements for the app |
Use cases
(For all use cases below, the System is the InterviewHub
and the Actor is the user
, unless specified otherwise)
Use case: UC01 - View help
MSS
- User requests to view help.
-
InterviewHub displays the help instructors.
Use case ends.
Use case: UC02 - Clear all data
MSS
- User requests to clear all data.
-
InterviewHub deletes all data.
Use case ends.
Use case: UC03 - View all applicants
MSS
- User requests to list all applicants.
-
InterviewHub displays a list of all applicants.
Use case ends.
Use case: UC04 - View all interviews
MSS
- User requests to list all interviews.
-
InterviewHub displays a list of all interviews.
Use case ends.
Use case: UC05 - Exit the application
MSS
- User requests to exit the application.
-
InterviewHub terminates gracefully.
Use case ends.
Use case: UC06 Add a new applicant
MSS
- User requests to add a new applicant.
-
InterviewHub adds the new applicant.
Use case ends.
Extensions
- 1a. The given command is invalid or one of the user-provided parameters is invalid.
-
1a1. InterviewHub shows an error message.
Use case resumes at step 1.
-
- 1b. The given applicant already exists in InterviewHub.
-
1b1. InterviewHub shows an error message.
Use case resumes at step 1.
-
Use case: UC07 Add a new interview
MSS
- User requests to add a new interview.
-
InterviewHub adds the new interview.
Use case ends.
Extensions
- 1a. The given command is invalid or one of the user-provided parameters is invalid.
-
1a1. InterviewHub shows an error message.
Use case resumes at step 1.
-
- 1b. The given interview already exists in InterviewHub.
-
1b1. InterviewHub shows an error message.
Use case resumes at step 1.
-
- 1c. The given interview causes a schedule clash.
-
1c1. InterviewHub shows an error message.
Use case resumes at step 1.
-
Use case: UC08 Delete an applicant
MSS
- User views the list of all applicants (UC03).
- User requests to delete a specific applicant.
-
InterviewHub deletes the specified applicant and any interviews the applicant was associated with.
Use case ends.
Extensions
- 2a. The provided index is invalid.
-
2a1. InterviewHub shows an error message.
Use case resumes at step 2.
-
Use case: UC09 Delete an interview
MSS
- User views the list of all interviews (UC04).
- User requests to delete a specific interview.
-
InterviewHub deletes the specified interview.
Use case ends.
Extensions
- 2a. The provided index is invalid.
-
2a1. InterviewHub shows an error message.
Use case resumes at step 2.
-
Use case: UC10 Edit an applicant
MSS
- User views the list of all applicants (UC03).
- User requests to edit a specific applicant.
-
InterviewHub edits the specified applicant and any interviews the applicant was associated with.
Use case ends.
Extensions
- 2a. The given command is invalid or one of the user-provided parameters is invalid.
-
2a1. InterviewHub shows an error message.
Use case resumes at step 2.
-
- 2b. The edited applicant already exists in InterviewHub
-
2b1. InterviewHub shows an error message.
Use case resumes at step 2.
-
Use case: UC11 Edit an interview
MSS
- User views the list of all interviews (UC04).
- User requests to edit a specific interview.
-
InterviewHub edits the specified interview.
Use case ends.
Extensions
- 2a. The given command is invalid or one of the user-provided parameters is invalid.
-
2a1. InterviewHub shows an error message.
Use case resumes at step 2.
-
- 2b. The edited interview already exists in InterviewHub.
-
2b1. InterviewHub shows an error message.
Use case resumes at step 2.
-
- 2c. The edited interview causes a schedule clash.
-
2c1. InterviewHub shows an error message.
Use case resumes at step 2.
-
- 2d. The selected interview to be edited is marked as done.
-
2d1. InterviewHub shows an error message.
Use case resumes at step 2.
-
Use case: UC12 - Find applicants
MSS
- User requests to find applicants.
-
InterviewHub finds and displays the applicants that match the user provided input.
Use case ends.
Use case: UC13 - Find interviews
MSS
- User requests to find interviews.
-
InterviewHub finds and displays the interviews that match the user provided input.
Use case ends.
Use case: UC14 - Marking an interview as done
MSS
- User requests to mark an interview.
-
InterviewHub marks the selected interview as done.
Use case ends.
Extensions
- 1a. The provided index is invalid.
-
1a1. InterviewHub shows an error message.
Use case resumes at step 1.
-
- 1b. The selected interview is already marked as done.
-
1b1. InterviewHub shows an error message.
Use case resumes at step 1.
-
Use case: UC15 - Rating an interview
MSS
- User requests to rate an interview.
-
InterviewHub updates the rating of the selected interview.
Use case ends.
Extensions
- 1a. The provided index is invalid.
-
1a1. InterviewHub shows an error message.
Use case resumes at step 1.
-
- 1b. The selected interview is not yet marked as done.
-
1b1. InterviewHub shows an error message.
Use case resumes at step 1.
-
- 1c. The provided rating is an invalid value
-
1c1. InterviewHub shows an error message.
Use case resumes at step1.
-
Use case: UC16 - View all completed interviews
MSS
- User requests to list all completed interviews.
-
InterviewHub displays a list of all completed interviews.
Use case ends.
Use case: UC17 - View all incomplete interviews
MSS
- User requests to list all incomplete interviews.
-
InterviewHub displays a list of all incomplete interviews.
Use case ends.
Use case: UC18 - View all interviews scheduled for today
MSS
- User requests to list all interviews scheduled for today.
-
InterviewHub displays a list of all interviews scheduled for today.
Use case ends.
Use case: UC19 - View all free time on a given date
MSS
- User requests to list all free time on a given date.
-
InterviewHub displays a list of all free time on a given date.
Use case ends.
Extensions
- 1a. The provided date is invalid.
-
1a1. InterviewHub shows an error message.
Use case resumes at step 1.
-
- 1b. The provided date is in the past.
-
1b1. InterviewHub shows an error message.
Use case resumes at step 1.
-
- 1c. The provided date contains no free time.
-
1c1. InterviewHub shows a blank message to denote that there is no free time.
Use case ends.
-
Use case: UC20 - Sort interviews in descending order of rating
MSS
- User requests to sort interviews in descending order of rating.
-
InterviewHub sorts the current list of interviews in descending order of rating.
Use case ends.
Use case: UC21 - Sort interviews in chronological order
MSS
- User requests to sort interviews in chronological order.
-
InterviewHub sorts the current list of interviews in chronological order.
Use case ends.
Non-Functional Requirements
- Should work on any mainstream OS as long as it has Java
11
or above installed. - Should be able to handle as many applicants as the user is able to manage in their workday/workweek.
- The app should be reasonably responsive to the entire set of user requests(i.e. within 1 second at maximum load).
- The system should have an interface that is very easy to pick up for our target audience(i.e. Engineering Hiring Managers that have many years of programming experience).
- This app is designed only to add interviewees and schedule interviews. Other parts of the interview process such as contacting applicants are not supported.
- The app should be ready for use within 5 seconds of the user launching the app
- It should support various screen resolutions and aspect ratios for optimal user experience on different devices.
- The application should be optimized to consume minimal system resources, such as CPU and memory, to ensure it runs smoothly on a wide range of desktop configurations.
- Users should receive clear and informative error messages in case of any issues, guiding them on how to resolve or report problems.
- The project is expected to adhere to a strict schedule that rolls out bug fixes and new features based on the needs of the clients.
Glossary
- Mainstream OS: Windows, Linux, Unix, OS-X/MacOS
- Private contact detail: A contact detail that is not meant to be shared with others
- Applicant: The applicant applying to a particular job role.
- Engineering Hiring manager: The manager interviewing the applicant. This manager is familiar with the technical aspects of the role.
- MSS: Main Success Scenario. It describes the most straightforward interaction in a use case where nothing goes wrong.
- Extensions: In a use case, an extension describes an alternative flow of events that are different from the MSS.
- CLI: Command Line Interface. It is text-based interface where users can input commands that interacts with the computer program.
Appendix: Planned Enhancement
-
The current error message when adding an interview where the start and/or end date string is a valid date but is missing time is too general. We plan to make the error message also mention why the command is not accepted and the reason for the failure: Please enter an interview time!
-
The current implementation of mark-i allows the user to mark interviews before the interview has been completed, based on the end time of the interview. We plan to not allow the user to mark interviews that have not passed. So, interviews whose end time is after the current time cannot be marked as done.
-
The current implementation of the find-i and find-a commands does not display a constant status of whether the find filter is being applied to the current list. E.g. When you perform a find-i command followed by some other command that changes the interview list, you have no way to tell if the previous “find-i” filter is still being applied. We plan to update the UI to display a constant status of what filter is currently being applied to the applicant and interview list.
-
The current implementation of the rating will set it to 0.0 when an interview object is first created. This is not ideal as the user is unable to differentiate whether the interview rating is truly 0.0. Therefore, the future plan is displaying the preset rating as N/A and the subsequent user rating will be the same as the current model.
-
The current implementation of applicant allows duplicate phone number and duplicate email to be entered into the system. Moreover, it prohibits name with the exact same string to be added. As the interview is identifiable mostly based on the name, allowing the same name string will result in confusion with the interview object. The future plan is to increase the visibility of the connection between applicant and interview, to remove dependency on the name itself. On the other hand, the duplication of phone number and email will be handled in future implementation and no longer allowing such duplication to be entered.
-
The current implementation of find-i does not allow searching for an empty string, which represents the job role when an applicant is applying to the company in general. We plan to allow find-i to search for “” (empty string) and “ “ (whitespaces) so that interviews with applicants that are applying to the company in general can be found with the command.
-
Currently, there is no way to unmark an interview after marking the interview since an interview’s status cannot change once it is done. However, some users may accidentally mark an unfinished interview as done. In the future, an unmark feature will be implemented to allow users to change the status of interviews from done to not done.
-
Currently, if any field belonging to an applicant or interview is too long (e.g. a very long name), the UI will truncate the text. In normal use, this is unlikely to occur as the text has to be unreasonably long to cause the truncation. However, this will be fixed in a future implementation which will allow horizontal scrolling on the applicant or interview card so that the user can see the full text.
Appendix: Instructions for manual testing
Given below are instructions to test the app manually.
Launch and shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder.
-
Open a terminal, and navigate to the folder you put the JAR file in.
-
Launch the app by using the command
java -jar InterviewHub.jar
in your terminal.
Expected: Shows the GUI with a set of sample applicants and interviews. The window size may not be optimum.
-
-
Saving window preferences
-
Resize the window to an optimum size. Move the window to your preferred location on the screen. Close the window.
-
Re-launch the app by using the command
java -jar InterviewHub.jar
in the same terminal.
Expected: The most recent window size and location is retained.
-
Viewing help
Command: help
- Test case:
help
Expected: Help window with the User Guide URL is displayed.
Clearing all the data
Command: clear
- Test case:
clear
Expected: All the applicants and interviews will be cleared. Success message is displayed.
Exiting the program
Command: exit
- Test case:
exit
Expected: Exits InterviewHub and all data is saved automatically.
Adding an applicant
Command: add-a
- Adding an applicant
- Test case:
add-a n/John Doe p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 t/engineer t/frontend
Expected: An applicantJohn Doe
is added with the phone number98765432
, emailjohnd@example.com
, address311, Clementi Ave 2, #02-25
and the tagsengineer
andfrontend
.
- Test case:
- Adding an applicant that has duplicate name
- Prerequisites: The applicant named
John Doe
added in the previous test is not deleted or changed name. - Test case:
add-a n/John Doe
Expected: No applicant is added. Error details shown in the status message.
- Prerequisites: The applicant named
Deleting an applicant
Command: delete-a
- Deleting an applicant while all applicants are being shown
- Prerequisites: List all applicants using the
list-a
command. Multiple applicants in the list. - Test case:
delete-a 1
Expected: First applicant is deleted from the list. Details of the deleted applicant shown in the status message. - Test case:
delete-a 0
Expected: No applicant is deleted. Error details shown in the status message.
- Prerequisites: List all applicants using the
- Deleting an applicant while no applicants are in the list
- Prerequisites: Clear all applicants using the
clear
command. List is empty. - Test case:
delete-a 1
Expected: No applicant is deleted. Error details shown in the status message.
- Prerequisites: Clear all applicants using the
Editing an applicant
Command: edit-a
- Editing an applicant while all applicants are being shown
- Prerequisites: List all applicants using the
list-a
command. Multiple applicants in the list. - Test case:
edit-a 1 n/Bob
Expected: First applicant’s name is edited toBob
. Details of the edited applicant shown in the status message. - Test case:
edit-a 0
Expected: No applicant is edited. Error details shown in the status message. - Test case:
edit-a 1
Expected: No applicant is edited. Error details shown in the status message.
- Prerequisites: List all applicants using the
Finding applicants from the list
Command: find-a
- Finding an applicant while all applicants are being shown
- Prerequisites: List all applicants using the
list-a
command. Multiple applicants in the list. One of the applicants is namedJohn Doe
. Another applicantAlex Yeoh
has phone number87438807
. No other applicant hasJohn
as part of their name. No other applicant has the number874
as part of their phone number. - Test case:
find-a n/John p/874
Expected: Two applicants are shown in the applicant list. The applicants shown areJohn Doe
andAlex Yeoh
. The number of applicants found is shown in the status message. - Test case:
find-a
Expected: List shown on GUI does not change. Error details shown in the status message. - Test case:
find-a n/
Expected: List shown on GUI does not change. Error details shown in the status message.
- Prerequisites: List all applicants using the
Listing all applicants
Command: list-a
- Listing all the applicants
- Test case:
list-a
Expected: Shows all the applicants in the applicant list. Success message is displayed.
- Test case:
Adding an interview
Command: add-i
- Adding an interview
- Prerequisites: List all applicants using the
list-a
command. Have at least one applicant that does not have an interview scheduled. Ensure that the input applicant ID chosen for stepii
belongs to an applicant which does not have an interview scheduled. (The border around the applicant should be red) - Test case:
add-i app/3 jr/Software Engineer start/12-12-2024 1500 end/12-12-2024 1600
Expected: An interview is added with the applicant at the target index on the applicant list, with the job roleSoftware Engineer
, starting datetime of12-12-2024 1500
and ending datetime of12-12-2024 1600
. - Test case:
add-i jr/PE Tester
Expected: No interview is added. Error details shown in the status message.
- Prerequisites: List all applicants using the
Deleting an interview
Command: delete-i
- Deleting an interview while all interviews are being shown
- Prerequisites: List all interviews using the
list-i
command. List all applicants using thelist-a
command. Multiple interviews in the list. - Test case:
delete-i 1
Expected: First interview is deleted from the list. Details of the deleted interview shown in the status message. The corresponding applicant associated with that interview should have their border turn from green to red - Test case:
delete-i 0
Expected: No interview is deleted. Error details shown in the status message.
- Prerequisites: List all interviews using the
- Deleting an interview while no interviews are in the interview list
- Prerequisites: Clear all interviews (and applicants) using the
clear
command (Note that this is irreversible). Interview list is empty. - Test case:
delete-i 1
Expected: No interview is deleted. Error details shown in the status message.
- Prerequisites: Clear all interviews (and applicants) using the
Editing an interview
Command: edit-i
- Editing an interview while all interviews are being shown
- Prerequisites: List all interviews using the
list-i
command. Multiple interviews in the list. Ensure that the selected interview index chosen for step2
belongs to an interview that is not marked as done (border around interview is red). - Test case:
edit-i 2 jr/PE Tester
Expected: The second interview’s job role is edited toPE Tester
. Details of the edited interview shown in the status message. - Test case:
edit-i 0
Expected: No interview is edited. Error details shown in the status message. - Test case:
edit-i 1
Expected: No interview is edited. Error details shown in the status message.
- Prerequisites: List all interviews using the
Finding interviews from the list
Command: find-i
- Finding interviews by job role
- Prerequisite: The interview with the indicated job role has matching keyword
- Test case:
find-i software
Expected: All interviews with at least onesoftware
(case-insensitive) as keyword in the job role are shown in the interview list. The amount of interview listed is shown on the status box. - Test case:
find-i
Expected: The interview list remained unchanged. Error message is displayed.
Listing all interviews
Command: list-i
- Listing all the interviews
- Test case:
list-i
Expected: Shows all the interviews in the interview list. Success message is displayed.
- Test case:
Listing all free timing for the given day
Command: list-freetime
- Listing the free time for a day using
DD/MM/YYYY
orDD-MM-YYYY
format- Prerequisites: The date string must be in the DD/MM/YYYY or DD-MM-YYYY format, and there should not be any interviews scheduled for the given date
- Test case:
list-freetime 12/12/2099
Expected: There should be 1 block of free time listed, which will span from 9am to 5pm on 12/12/2099 - Test case:
list-freetime 12-12-2099
Expected: There should be 1 block of free time listed, which will span from 9am to 5pm on 12/12/2099 - Success message shown in command box for both cases:
Free times on 12/12/2099:
from: 09:00 to: 17:00
- Listing the free time for a day using
DD/MM
orDD MMM
format, where- Prerequisites: The date string must be in the DD/MM or DD MMM format, and there should not be any interviews scheduled for the given date
- Test case:
list-freetime 12/12
Expected: There should be 1 block of free time listed, which will span from 9am to 5pm on 12/12/2023 - Test case:
list-freetime 12 Dec
Expected: There should be 1 block of free time listed, which will span from 9am to 5pm on 12/12/2023 - Success message shown in command box for both cases:
Free times on 12/12/2023:
from: 09:00 to: 17:00
- Listing the free time for a date in the past
- Prerequisite: The date string must follow one of the accepted date formats
- Test case:
list-freetime 12-12-1970
Expected: Command does not execute. - Error message shown in command box:
Input date cannot be in the past!
Listing all interviews for today
Command: list-i-today
- Listing all interviews today
- Test case:
list-i-today
Expected: Shows all interviews scheduled for today (i.e. the date when the command was executed) in the interview list. Success message is displayed.
- Test case:
Marking an interview as done
Command: mark
- Marking an interview as done
- Prerequisites: the interview must not be marked as done(red border displayed).
- Test case:
mark 1
Expected: Mark the first interview as done(green border). Success message is displayed.
- Marking an interview that has already been marked as done
- Prerequisites: the interview must already been marked as done(green border displayed).
- Test case:
mark 1
Expected: Error message is displayed.
Rating an interview
Command: rate
- Rating an existing interview
- Prerequisites: the interview to be rated has been marked as done, and it exists in the list.
- Test case:
rate 1 2.0
Expected: The interview rating at index one has been updated to 2.0. Success message is displayed. - Test case:
rate 1 10.0
Expected: The interview rating at index one is not changed. Error message is displayed.
Listing all completed interview
Command: list-i-done
- Listing completed interviews with exact command
- Test case:
list-i-done
Expected: The interview list should only show interviews which have been completed (i.e. those that are green). If there are no completed interviews, the interviews box will be empty
- Test case:
- Listing completed interviews with the command along with nonsensical parameters appended to the end
- Test case:
list-i-done I am a cat
Expected: Same expected result as test case 1
- Test case:
Listing all incomplete interview
Command: list-i-not-done
- Listing completed interviews with exact command
- Test case:
list-i-not-done
Expected: The interview list should only show interviews which have been completed (i.e. those that are green). If there are no completed interviews, the interviews box will be empty
- Test case:
- Listing completed interviews with the command along with nonsensical parameters appended to the end
- Test case:
list-i-not-done I am a cat
Expected: Same expected result as test case 1
- Test case:
Sorting the interview list by rating
Command: sort-rate
- Sorting the current interview list by rating.
- Test case:
sort-rate
Expected: Sorts the current interview list by rating in descending order. Success message is displayed.
- Test case:
Sorting the interview list by start-time
Command: sort-time
- Listing completed interviews with exact command
- Test case:
sort-time
Expected: The interview list will be sorted in chronological order of start times. If there are no interviews scheduled, the interviews box will be empty. In the case that the list is filtered in some way, the sort will only sort on the filtered interview list
- Test case:
- Listing completed interviews with the command along with nonsensical parameters appended to the end
- Test case:
sort-time I am a cat
Expected: Same expected result as test case 1
- Test case: