By: CS2113T-AY1819S1 Team F10-1 Since: Aug 2018 Licence: MIT

1. Setting up

1.1. Prerequisites

  1. JDK 9 or later

  2. IntelliJ IDE

    IntelliJ by default has Gradle and JavaFX plugins installed.
    Do not disable them. If you have disabled them, go to File > Settings > Plugins to re-enable them.

1.2. Setting up the project in your computer

  1. Fork this repo, and clone the fork to your computer

  2. Open IntelliJ (if you are not in the welcome screen, click File > Close Project to close the existing project dialogue first)

  3. Set up the correct JDK version for Gradle

    1. Click Configure > Project Defaults > Project Structure

    2. Click New…​ and find the directory of the JDK

  4. Click Import Project

  5. Locate the build.gradle file and select it. Click OK

  6. Click Open

  7. Click OK to accept the default settings

1.3. Verifying the setup

  1. Run the src.classrepo.Main and try a few commands

  2. Run the tests to ensure they all pass

  3. Open the StorageFile file and check for any code errors

    1. Due to an ongoing issue with some of the newer versions of IntelliJ, code errors may be detected even if the project can be built and run successfully

    2. To resolve this, place your cursor over any of the code section highlighted in red. Press ALT+ENTER, and select Add '--add-modules=java.xml.bind' to module compiler options

1.4. Configurations to do before writing code

1.4.1. Configuring the coding style

This project follows oss-generic coding standards. IntelliJ’s default style is mostly compliant with ours but it uses a different import order from ours. To rectify,

  1. Go to File > Settings…​ (Windows/Linux), or IntelliJ IDEA > Preferences…​ (macOS)

  2. Select Editor > Code Style > Java

  3. Click on the Imports tab to set the order

    • For Class count to use import with '*' and Names count to use static import with '*': Set to 999 to prevent IntelliJ from contracting the import statements

    • For Import Layout: The order is import static all other imports, import java.*, import javax.*, import org.*, import com.*, import all other imports. Add a <blank line> between each import

Optionally, you can follow the UsingCheckstyle.adoc document to configure Intellij to check style-compliance as you write code.

1.4.2. Updating documentation to match your fork

After forking the repo, the documentation will still have the SE-EDU branding and refer to the se-edu/addressbook-level3 repo.

If you plan to develop this fork as a separate product (i.e. instead of contributing to se-edu/addressbook-level3), you should do the following:

  1. Configure the site-wide documentation settings in build.gradle, such as the site-name, to suit your own project.

  2. Replace the URL in the attribute repoURL in DeveloperGuide.adoc and UserGuide.adoc with the URL of your fork.

1.4.3. Setting up CI

Set up Travis to perform Continuous Integration (CI) for your fork. See UsingTravis.adoc to learn how to set it up.

After setting up Travis, you can optionally set up coverage reporting for your team fork (see UsingCoveralls.adoc).

Coverage reporting could be useful for a team repository that hosts the final version but it is not that useful for your personal fork.

Optionally, you can set up AppVeyor as a second CI (see UsingAppVeyor.adoc).

Having both Travis and AppVeyor ensures your App works on both Unix-based platforms and Windows-based platforms (Travis is Unix-based and AppVeyor is Windows-based)

1.4.4. Getting started with coding

When you are ready to start coding,

  1. Get some sense of the new features added on from AddressBook-Level 3 by se-edu by reading Section 2, “Implementation”.

2. Implementation

This section describes some noteworthy details on how certain features are implemented.

2.1. Exams Feature

Exam
Figure 1. Class Diagram of the Exam feature

2.1.1. Current Implementation

There is a master ExamBook which contains all the exams. There are several features the ExamBook offers. The main features are:

  1. Adding a new exam

  2. Deleting an exam

  3. Editing an exam

  4. Registering a person for an exam

  5. Deregistering a person for an exam

Changes to the master ExamBook will affect the corresponding exams in the AddressBook. This is done through iterating through the AddressBook to update the change. Changes in the AddressBook will also affect the exams the persons registered for in the ExamBook and hence, for other persons in the AddressBook. This is also done through iterating.

An Example of how feature 5 - Registering a person for an exam works:

  1. First, the specific exam and person will be identified from the most recent exams and persons listing respectively.

  2. The specific exam and person is then extracted out of the ExamBook and AddressBook respectively.

  3. A check is performed to ensure the specific person is not already registered for the exam.

  4. A new exam is created to keep a copy of the original exam.

  5. The exam has its number of exam takers increased by 1.

  6. The exam is added to the specific person.

  7. For the AddressBook, any copies of the original exam are removed and replaced with the new exam.

This is demonstrated by the following sequence diagram:

RegisterExam Sequence Diagram
Figure 2. Sequence Diagram of registering a person for an exam with no errors occurring

2.1.2. Design Considerations

Aspect: How the exam data are being synchronised between the AddressBook and ExamBook
  • Alternative 1 (current choice): Each time there is a change in the field of an Exam, there has to be iteration through the whole AddressBook or ExamBook to update them.

    • Pros: Less space is needed.

    • Cons: This can waste some time if no changes need to be made for example.

  • Alternative 2: Store the persons registered for an exam for each exam.

    • Pros: This makes it faster to update any changes in both AddressBook and ExamBook if needed.

    • Cons: More data is duplicated and stored in both AddressBook and ExamBook.

Aspect: How the exam data are being updated
  • Alternative 1 (current choice): Each time there is a change in a field of an Exam, a new Exam is created with the new details and added into the ExamBook and the old Exam is deleted from the ExamBook.

    • Pros: To enable good synchronisation between the AddressBook and ExamBook as the old hash key is removed and a new hash key is added.

    • Cons: Temporary increase in space for the object created during the method.

  • Alternative 2: Edit the original exam directly.

    • Pros: Easy access to set values.

    • Cons: To check if an exam exists for a person, there needs to be iteration and checks using the equals() method due to different hashing, increasing time.

Aspect: Exam equality
  • Alternative 1 (current choice): The current equals() method does not check for full equality.

    • Pros: This is used when there is not a need to check for full equality, such as when adding a new exam to the ExamBook.

    • Cons: Another method is needed to check for full equality.

  • Alternative 2: Have the current equals() method check for full equality, with no extra methods.

    • Pros: Fewer methods and easier to understand implementation.

    • Cons: Duplicate exams can be added, especially after modification of an exam in the ExamBook.

Aspect: Data structure to support the exam commands
  • Alternative 1 (current choice): Exams are stored in a set under each Person object in the AddressBook but stored as a list in the ExamBook.

    • Pros: In the Exambook, it is required to access an exam through an index to delete and edit, hence list is better. In the AddressBook, exams are only to be used for viewing and accessed to check for the value. It takes O(1) time to check for existence and remove and add.

    • Cons: Exams stored under each Person in the AddressBook cannot be sorted.

  • Alternative 2: Exams are stored as a list in both ExamBook and AddressBook.

    • Pros: Exams stored under each Person in the AddressBook can be sorted.

    • Cons: It takes O(n) time (longer time) to check if a Person has a same Exam with the Exam to be updated.

Aspect: Storage of ExamBook
  • Alternative 1 (current choice): Exams are stored in a separate txt file from AddressBook

    • Pros: This allows for clarity and easy access to find and see exams in raw XML format.

    • Cons: Extra storage file and hence methods and file paths are needed, this may be confusing and cause much repetition of code.

  • Alternative 2: Exams are stored in the same data file as AddressBook.

    • Pros: Only 1 storage file is needed. Less repetition and variables are needed.

    • Cons: Might be harder for the user to see exams in raw XML format as everything is stored together.

2.2. Privilege/Account Feature

The Privilege feature aims to only restrict the user’s interaction to their allowed commands, while the Account feature provides a means for the user to authenticate himself/herself to access more commands.


The figure below shows the class diagram describing the implementation of the Privilege/Account feature.

PrivilegeClassDiagram
Figure 3. Class Diagram of the Privilege Component

2.2.1. Current Implementation

  • Logic is assigned to one Privilege object at all times. Privilege contains a User (specified by the PrivilegeLevel enum) and a Person (referred to as myPerson).

  • The User interface describes the different Privilege level an user can have, which is implemented by BasicUser, TutorUser and AdminUser.

  • BasicUser is the class with the lowest access level, and the ancestor to other 2 User classes.

  • To create an increasing level of access, each User of a higher level inherits from the successively lower one.

  • User levels have their own list of new commands they can run, which is appended to the list inherited from their parent.

  • Account class, which contains its respective Privilege object as well as login details, assigns a Privilege level to a Person.

An example of how logging into an account works:

  1. First, the Command will retrieve the Person with the specified username, which is gotten from AddressBook who receives it from UniquePersonList.

  2. The Command then validates that the specified password matches the password the Account belonging to the retrieved person.

  3. If the password is correct, the Command will update the Privilege level(user) and its Person(myPerson) to match that of the Account.

  4. Finally, the Command retrieve the Name of the Person in a string format to be printed as part of the feedback message.

Step 3 is illustrated in the Object Diagram below.

PrivilegeObjectDiagram
Figure 4. How switching Privilege is implemented (Object Diagram)

The Sequence Diagram below gives an overview of the process involved in logging into an Account

Login Sequence Diagram
Figure 5. Sequence Diagram for Login Command

2.2.2. Design Considerations

Aspect: How to define a privilege level of Privilege
  • Alternative 1 (current choice): Instantiate User objects of the different access level. Privilege contains an enum UserType which point to each of these instantiated objects.

    • Pros: Allow us to make use of inheritance to organize the list (higher access level User’s list of allowed Commands will always be a superset of that of a lower access level).
      The usage of enums also allows us to keep a reference to the created User object, which allows us to point back to these object if need be, rather than having to instantiate new ones each time.

    • Cons: Requires the use of User class to represent the different access levels

  • Alternative 2: Use an enum to indicate the current access level. List of allowed Commands will be generated base on the value of this enum.

    • Pros: Does not require a separate class to represent the different Privilege levels.

    • Cons: Difficult to maintain the list of allowed Commands.

  • Alternative 3: Use a String to determine the Privilege level.

    • Pros: Easy to implement and parse.

    • Cons: Very prone to undetected bugs, like misspelling the Privilege levels.

Aspect: How to define the required Privilege level of Commands
  • Alternative 1 (current choice): Each User holds a list of Commands they can run

    • Pros: Easy to maintain the list of available Commands for a given User.

    • Cons: Difficult to find the required Privilege level a Command, as it requires looping through the list to find the presence of the given Command.

  • Alternative 2: Each Command knows what access level is required to run it

    • Pros: Easy to find what access level a Command requires

    • Cons: Difficult to see the Commands available to a given User can run, thus making it hard to organize the Commands by their required access level.

  • Alternative 3: Have both 1 and 2

    • Pros: Doing both the above operations become easy

    • Cons: Difficult to maintain both information. The required Privilege level for Commands will be stored in 2 separate locations and needs to be in sync.

Aspect: How to update the Privilege of Logic when logging into an Account
  • Alternative 1 (current choice): The Privilege object attached to Logic will copy the User and the Person attached to the given Account object, into its own variables.

    • Pros: Does not require the Command to interact with Logic, thus reducing coupling.

    • Cons: A bit more awkward solution than the Alternative 2

  • Alternative 2: Make Logic’s variable to point to the new Privilege object inside of Account.

    • Pros: Quick to implement.

    • Cons: Has a higher level of coupling compared to Alternative 1. Also, would require storing or instantiating a default Privilege object and making a Logic point to this new object if Logout Command were to be called.

Aspect: Default required access levels for Commands
  • Alternative 1 (current choice): Required Privilege level is set to Admin by default

    • Pros: If a developer forgets to assign a required Privilege level to a Command, it will to still be functional.

    • Cons: May mask the fact that the Command has the unintended access level of Admin, which is a minor drawback.

  • Alternative 2: Enforce all Commands to be assigned an access level

    • Pros: Forces developers to be deliberate with their access level assigned to Commands.

    • Cons: Program will fail to integrate if any of the developers forgot to assign an access level to their newly developed Command.

Aspect: Who throws InsufficientPrivilege Exception
  • Alternative 1 (current choice): Logic throws the Exception

    • Pros: It is a common starting point of commands, so it is easy to implement it to throw the Exception

    • Cons: Blurs the responsibility of Commands being the one throwing Exceptions

  • Alternative 2: Each Command checks the Privilege level during execute()

    • Pros: Keeps to the responsibility of Commands being the one to throw the Exception.

    • Cons: Requires backdating all Commands to include this function in their execute(). Also prone to errors as a developer may forget to call this function in their execute() of their newly developed Command.

  • Alternative 3: Have a function that checks the Privilege level in parent command that is called during execute()

    • Pros: Same as Alternative 2.

    • Cons: Same as Alternative 2, but instead of using individual functions, we are repeatedly using the inherited function instead

2.3. Grades Feature

2.3.1. Current Implementation

There is a master StatisticsBook which contains all the statistics for various exams. There is also a list of assessments and the grades for these assessments being stored in the AddressBook. The current set of commands include:

  1. Adding a new assessment

  2. Listing all assessments

  3. Deleting an assessment

  4. Adding grades for a student

  5. Viewing all grades for a student

  6. Deleting a specific grade for a student

  7. Adding statistics for an assessment

  8. Listing all statistics

  9. Deleting a statistic

This is the class diagram for the assessments, grades and statistics combined:

AssessmentClassDiagram
Figure 6. Class Diagram
  1. A list of unique assessments can be stored in the AddressBook.

  2. Each assessment object contains a Hash Map, with Person as the Key and Grades as the Value. Hence, the grades of all students for a particular assessment will be stored together in the same HashMap.

  3. Each person object (or student) can have a list of assessments and respective grades under it. This makes sense logically since a student will have multiple assessments throughout the school year.

  4. Statistics can be added for an existing assessment. The grades stored in the HasHMap will be used to calculate various stats such as average score, total exam takers, max score and min score.

  5. This list of statistics is stored in the statisticsbook.

An Example of how feature 2 - Adding a new assessment to the AddressBook works:

  1. The user (teacher/ admin) will be able to use the 'addassess' command to add a new assessment.

  2. This assessment will only be added to the AddressBook if it is not already present. i.e. check for duplicate assessments is done.

  3. These assessments reflect the exams/homework of the school in general. This list of assessments can then be used to add grades to a particular student.

This is demonstrated by the following sequence diagram:

Assessment Seq Diagram
Figure 7. Sequence Diagram of adding a new assessment

2.3.2. Design Considerations

Aspect: 'Assessment' and 'Grades' as separate classes
  • Alternative 1 (current choice): Assessments and Grades are created as two separate classes. Assessment class stores the grades of all students for that assessment in a HashMap, where the Person (or student) is the key.

    • Pros: Better design in terms of OOP. Allows easier calculation of statistics per assessment as you can simply loop through all the grades. It is also a good model of the real world where all grades for an assessment will be stored together.

    • Cons: This is a little more tedious in terms of coding.

  • Alternative 2: The Assessment and Grades are combined into a single class with different parameters to take in the exam name and grade respectively.

    • Pros: - Storage of the data becomes a little easier and you can just store a list of grades added to each person.

    • Cons: Cannot view the list of assessments separately. This architecture does not make sense in terms of modelling how grades are stored in the real world.

Aspect: Data structure to store grades
  • Alternative 1 (current choice): The grades are stored using a Map data structure under Assessment class

    • Pros: Allows easy reference to person class.

    • Cons: Cannot sort/ order the entries if required.

  • Alternative 2: The grades are stored using a 'List' data structure under Assessment class

    • Pros: Can sort the grades alphabetically if required.

    • Cons: Difficult to link grades to person.

Aspect: Creation and Storage of Statistics Book
  • Alternative 1 (current choice): A separate Statistics Book is created to store the statistics of all assessments. Also, these statistics are stored in a separate txt file (statistics.txt) from AddressBook

    • Pros: These assessment statistics have no direct link to the person object. It is a separate set of information accessible to all users (students, teachers and admin). Hence, a separate Statistics Book provides increased clarity and makes sense in terms of the end-usage. This also gives easy access to find and see statistics in raw XML format.

    • Cons: Using an extra storage file implies that additional methods and file paths are needed. Makes code lengthier and repetitive.

  • Alternative 2: Store statistics in AddressBook itself.

    • Pros: Everything is condensed and can be found in the same spot. Also, only one storage file would be needed.

    • Cons: It is messy and confusing in terms of implementation - Unrelated data is being stored together.

Aspect: Automatic calculation of statistics
  • Alternative 1 (current choice): A fixed set of statistics (average score, the total number of exam takers, max score and min score) are automatically calculated inside the application itself.

    • Pros: Reduces human effort. Makes the process of creating a statistic easier for the user as they would not have to use any external tools like Excel to do this.

    • Cons: Only the statistics parameters currently built into the app can be added. If the user wants to add any other parameter like pass rate, then it is currently not possible.

  • Alternative 2: The user manually calculates statistics using given data by hand and enters it in the app to store.

    • Pros: The user can choose to leave some field blank if wanted.

    • Cons: Extremely tedious. Against the whole point of digitizing the school management as manual paperwork is still involved.

2.3.3. Aspect: XML Storage of Assessments and Grades

  • Alternative 1 (current choice): Two concurrent lists are used to store the person index (as per latest person list) and respective grades for each assessment.

    • Pros: Since each student only has one grade per assessment, it is practical to store them as lists. Essentially, the keys of the hash map (in index form) and the values are stored as two separate lists. The corresponding pairs can be obtained by reading the entries at the same index in both lists.

    • Cons: This is an adaptation of the HashMap used to store grades in the code.

  • Alternative 2: Store the grades as a list of pairs (person index and grade value) for each assessment

    • Pros: Storage is more coherent.

    • Cons: Code is lengthier and more strenuous to write.

2.4. Fees Feature

FeesClassDiag
Figure 8. Class Diagram of Fees

Fees are an additional field to every Person object:

  1. Each Person will have a Fees object

  2. Fees contain both a String value as well as a String duedate

  3. Users can thus check the Fees of a particular person, or list out all the fees of the Persons in the AddressBook

2.4.1. Current Implementation

An attribute under the Person class is initialised when a Person is added to the AddressBook. This attribute holds 2 Strings, one being the monetary value of the fee and the other being the duedate for that respective fee. The current set of commands include:

  1. Editing a Fee

  2. Paying a Fee in full

  3. Viewing Fee of a Person

  4. Listing all Fees

  5. Listing all Due Fees

An Example of how command 1 - Editing the Fee of a Person works:

  1. The admin will be able to use the 'editfees' command to add a new fee to the Person.

  2. The existing fee with its date will be replaced by this new value in the Person object in the AddressBook.

  3. The updated fees will then be stored in the AddressBook and will be automatically private, only viewable by the admin and tutors.

This is shown in the diagram below.

EditFeesSequenceDiag
Figure 9. Sequence Diagram of EditFeesCommand

2.4.2. Design Considerations

Aspect: How to define a Fee for each Person
  • Alternative 1 (current choice): Instantiate Fee attribute under each Person created in the Person Class.

    • Pros: Allow us to skip the need for another data Class to be saved into any of the storage files, therefore being more convenient and reducing the number of files and Books.

    • Cons: May get messy with more data manipulation of the Fees attribute when printing/sorting.

  • Alternative 2: Use a separate date file 'FeesBook' to keep track of each Person and their respective fees.

    • Pros: Data independency and hence no conflict during data manipulation.

    • Cons: Cluttered as there may be too many data Books just to track an attribute.

  • Alternative 3: A compulsory attribute under Person Class hence occupying a data field in the input for AddPersonCommand.

    • Pros: Easy to implement and parse.

    • Cons: Input for Add Command would be too long as it will have too many data entry points.

Aspect: Paying a fee for a Person
  • Alternative 1 (current choice): Separate command for Admin to indicate a Person to have paid fees fully.

    • Pros: Convenient for admins to control Fees data of each Person.

    • Cons: May seem redundant for 2 Commands to change the attributes of Fees.

  • Alternative 2: Using EditFeesCommand to indicate the payment of Fees when edited back to 0 value.

    • Pros: Lesser commands in the Fees feature, therefore lesser clutter.

    • Cons: Counterintuitive as Admin would have to manually edit values to be "0.00".

Aspect: How to List fees of everyone
  • Alternative 1 (current choice): Shallow copies the internalList of ReadOnlyPerson, sorts the copy with a custom comparator and prints the list, showing only name and fees.

    • Pros: Allows for easy sorting and does not manipulate the date in the original internalList.

    • Cons: Does not allow for any data manipulation such as omitting any Person

  • Alternative 2: Looping through internalList and printing every name and respective Fee.

    • Pros: Easy to implement.

    • Cons: Unable to be sorted by the date dues of the Fees of each Person.

Aspect: Having another ListDueFeesCommand
  • Alternative 1 (current choice): Having another Command which only shows the people that have Fees that are due with respect to the current system date.

    • Pros: Clearer presentation of data and specific Persons involved. Ability to add "feesdue" tag to only the people shown.

    • Cons: May seem redundant as these people already appear at the top of ListFeesCommand.

  • Alternative 2: Merging it with ListFeesCommand, therefore only have one List Command with respect to Fees.

    • Pros: Less clutter of code.

    • Cons: Inability to show the list of Fees of the Persons whose Fees are not yet due. Restricted in presenting data.

Aspect: Using ViewFeesCommand with respect to INDEX
  • Alternative 1 (current choice): Follows the other ViewCommands with respect to the last INDEX presented following any List Command.

    • Pros: Coherent code template as all ViewCommands follow the INDEXED structure. Ability to be flexible depending on which List Command was called beforehand.

    • Cons: May not seem intuitive to view Fee of a specific Person if User only knows Name of the Person, therefore leading to use of the Find Command first.

  • Alternative 2: Using another parameter such as Name of the Person, instead of INDEX

    • Pros: More intuitive to layman Users.

    • Cons: There may be Persons with identical names, thus resulting in conflicts in ViewCommand.

2.5. Attendance Feature

ClassDiagram Attendance
Figure 10. Class Diagram of the Attendance feature
ClassDiagram Attendance with Methods
Figure 11. Class Diagram that links from UniquePersonList to Attendance object, including methods

The attendance field is an additional field to every Person object:

  1. Each Person will have an Attendance object

  2. Each Attendance object will contain a Hashmap, which will store the attendance of each person by keying each String date to a boolean isPresent.

  3. UniquePersonList will contain 2 lists, containing a list of people who are present or absent for each particular date.

  4. Users can thus check the attendance of a particular person, or for a particular date.

2.5.1. Current Implementation

The AddressBook contains the attendance of each person for each date that his/her attendance is taken. The current set of commands include:

  1. Updating a person’s attendance

  2. Replacing a person’s attendance

  3. Viewing of a person’s attendance

  4. Viewing of present people on a particular date

An example of how feature 1 - Updating a person’s attendance works:

  1. The user (teacher/ admin) will be able to use the 'attendance' command to update the attendance of a particular person (student).

  2. The specific person is extracted from the AddressBook.

  3. A check is performed to check if the person already has his/her attendance taken.

  4. If the attendance has already been taken, the user will be prompted to use another command replaceAtten to replace the attendance.

  5. If the attendance has yet to be taken, the attendance of the specified person for the specified date will be taken as either 'present' or 'absent'.

2.5.2. Design Considerations

Aspect: How to store attendance for each person
  • Alternative 1 (Current choice): Each person has a hashmap that stores the date to the attendance.

    • Pros: Hashmaps allows more efficient checking of duplicate attendance (get() method has a complexity of O(1).

    • Cons: Values and Keys in hashmap are not sorted.

  • Alternative 2: Each person has a list of strings containing the date and attendance.

    • Pros: A list of strings will allow easier storage and viewing of the data

    • Cons: List or ArrayList will require O(n) time to check for duplicates

    • Cons: A single string will not allow handling of data separately

  • Alternative 3: Each person has a list of pairs containing date and attendance.

    • Pros: Pairing of date to attendance ensures that the checking of attendance requires at most O(n) time, but minimally O(1)

    • Cons: Usage of pairs in java will require an extra class or an external library, which is unnecessary

Aspect: How to check if attendance has duplicate
  • Alternative 1 (Current choice): Use a boolean to check if there is a duplicate date in the hashmap.

    • Pros: Booleans only have 2 value, and thus there is no need to define a string with a proper variable name

    • Cons: Booleans are fixed as true and false, thus needed additional code to translate the result into a string so that the user can understand the results easily.

  • Alternative 2: Use a separate class, 'hasDuplicate' to check for duplicate date

    • Pros: An additional class means that the code will be more encapsulated, fulfilling the purpose of OOP.

    • Cons: Additional code will be required to create the additional class

Aspect: How to differentiate between updating and replacing a person’s attendance
  • Alternative 1 (Current choice): Using an additional parameter (Boolean overWrite) that is fixed in the command.

    • Pros: No confusion for the user since the parameter to overwrite is fixed.

    • Pros: THere is no need to have 2 separate methods in the Attendance object as both updating and replacing of attendance has very similar functions.

    • Cons: There is a need to check for an additional parameter in the same method, which may lengthen the code and cause minor 'arrowhead' coding.

  • Alternative 2: Treat the 2 commands as 2 completely separate commands and execute them individually.

    • Pros: The 2 commands will each be short, simple and easy to understand.

    • Cons: There will be 2 methods with extremely similar functions, which is redundant.

  • Alternative 3: Have the user input an additional parameter (Boolean overWrite) if they want to overwrite the current data

    • Pros: Similar to alternative 1, having the user input an additional parameter and only having 1 method in the Attendance object can reduce the need to have unnecessary duplicates in the code.

    • Cons: An additional parameter will require a change in the parser.

Aspect: How to store data in XML, addressbook.txt
  • Alternative 1 (Current choice): Use 2 list to store a list of dates and a list of absent/present

    • Pros: Simple implementation, and utilizes the fact that each date can only have either present/absent. Iterating through the map to generate the 2 lists will thus ensure that the data is in order

    • Cons: In the XML format, data will be stored as 2 separate lists, which may not be as user-friendly to edit directly.

  • Alternative 2: Use a list of pairs, Pair <String Date, Boolean isPresent>

    • Pros: Only requires 1 single list to store the data of the entire map.

    • Cons: Such implementation will require a Pair object, which will require additional methods and classes, thus requiring longer code.

  • Alternative 3: Convert Hashmap to XML directly

    • Pros: Direct transfer of data will thus require less memory space to store the same data.

    • Cons: A Hashmap to XML converter will require either a very long code (unnecessary for only 1 map), or requires the import of an external library.

2.5.3. Coming in v2.0

Aspect: : How to implement multiAtten Command
  • Alternative 1 (Most likely choice): multiAtten command calls the attendance command multiple times

    • Pros: Reduce the need for repeated code since the multiAtten command is very similar to attendance command.

    • Pros: Simpler to implement when the input is 0 as there is no need to catch index 0 since index 0 will not exist in the UniquePersonList.

    • Cons: Increase in coupling as a change in attendance command will cause multiAtten command to change.

  • Alternative 2 (Unlikely choice): Reimplement the command as a brand new command

    • Pros: Cleaner codes

    • Pros: A brand new implementation would allow for future upgrades

    • Cons: Lengthier and repeated code

3. Documentation

We use asciidoc for writing documentation.

We chose asciidoc over Markdown because asciidoc, although a bit more complex than Markdown, provides more flexibility in formatting.

3.1. Editing Documentation

See UsingGradle.adoc to learn how to render .adoc files locally to preview the end result of your edits. Alternatively, you can download the AsciiDoc plugin for IntelliJ, which allows you to preview the changes you have made to your .adoc files in real-time.

3.2. Publishing Documentation

See UsingTravis.adoc to learn how to deploy GitHub Pages using Travis.

3.3. Converting Documentation to PDF format

We use Google Chrome for converting the document to PDF format, as Chrome’s PDF engine preserves hyperlinks used in web pages.

Here are the steps to convert the project documentation files to PDF format.

  1. Follow the instructions in UsingGradle.adoc to convert the AsciiDoc files in the docs/ directory to HTML format.

  2. Go to your generated HTML files in the build/docs folder, right click on them and select Open withGoogle Chrome.

  3. Within Chrome, click on the Print option in Chrome’s menu.

  4. Set the destination to Save as PDF, then click Save to save a copy of the file in PDF format. For best results, use the settings indicated in the screenshot below.

chrome save as pdf
Figure 12. Saving documentation as PDF files in Chrome

3.4. Site Template

The files in docs/stylesheets are the CSS stylesheets of the site. You can modify them to change some properties of the site’s design.

The files in docs/templates controls the rendering of .adoc files into HTML5. These template files are written in a mixture of Ruby and Slim.

Modifying the template files in the docs/templates requires some knowledge and experience with Ruby and Asciidoctor’s API. You should only modify them if you need greater control over the site’s layout than what stylesheets can provide. The SE-EDU team does not provide support for modified template files.

4. Testing

4.1. Running Tests

There are two ways to run tests.

Method 1: Using IntelliJ JUnit test runner

  • To run all tests, right-click on the src/test/java folder and choose Run 'All Tests'

  • To run a subset of tests, you can right-click on a test package, test class, or a test and choose Run 'ABC'

Method 2: Using Gradle

  • Open a console and run the command gradlew clean test (Mac/Linux: ./gradlew clean test)

See UsingGradle.adoc for more info on how to run tests using Gradle.

4.2. Types of tests

We have 3 types of test:

  1. Non-GUI Tests - These are tests not involving the GUI. They include,

    1. Unit tests targeting the lowest level methods/classes.
      e.g. classrepo.commons.UtilsTest

    2. Integration tests that are checking the integration of multiple code units (those code units are assumed to be working).
      e.g. StorageFileTest

    3. Hybrids of unit and integration tests. These tests are checking multiple code units as well as how they are connected together.
      e.g. LogicTest

5. Dev Ops

5.1. Build Automation

See UsingGradle.adoc to learn how to use Gradle for build automation.

5.2. Continuous Integration

We use Travis CI and AppVeyor to perform Continuous Integration on our projects. See UsingTravis.adoc and UsingAppVeyor.adoc for more details.

5.3. Coverage Reporting

We use Coveralls to track the code coverage of our projects. See UsingCoveralls.adoc for more details.

5.4. Documentation Previews

When a pull request has changed to asciidoc files, you can use Netlify to see a preview of how the HTML version of those asciidoc files will look like when the pull request is merged. See UsingNetlify.adoc for more details.

5.5. Making a Release

Here are the steps to create a new release.

  1. Update the version number in Main.java.

  2. Generate a JAR file using Gradle.

  3. Tag the repo with the version number. e.g. v0.1

  4. Create a new release using GitHub and upload the JAR file you created.

5.6. Managing Dependencies

A project often depends on third-party libraries. For example, AddressBook depends on the Jackson library for XML parsing. Managing these dependencies can be automated using Gradle. For example, Gradle can download the dependencies automatically, which is better than these alternatives.
a. Include those libraries in the repo (this bloats the repo size)
b. Require developers to download those libraries manually (this creates extra work for developers)

Appendix A: Product Scope

Target user:
Students, teachers and staff of Secondary Schools.

Target user profile:

  • has a need to manage a significant number of contacts

  • prefer desktop apps over other types

  • can type fast

  • prefers typing over mouse input

  • is reasonably comfortable using CLI apps

  • differences on how each group may interact with the system

Value proposition: manage contacts faster than a typical mouse/GUI driven app

Appendix B: User Stories

Click to Expand

Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *

Priority As a …​ I want to …​ So that I can…​

* * *

new user

see usage instructions

refer to instructions when I forget how to use the App

* * *

user

login to my account

access my account

* * *

user

log out of my account

other people cannot use my account after logging out

* * *

user

find a person by name

locate details of persons without having to go through the entire list

* * *

first admin

raise my privilege to admin

have the initial privilege to access restricted commands

* * *

admin

add a new person

* * *

admin

delete a person

remove entries that I no longer need

* * *

admin

change the master password

have a password that is more suitable/easier to remember

* * *

admin

add accounts to people

other people can have an account to log in to

* * *

admin

delete accounts from people

remove the account from people who do not need it anymore

* * *

admin

add a new exam

* * *

admin

delete an exam

remove entries that I no longer need

* * *

admin

edit an exam

update the details of exam entries

* * *

admin

hide private exams

not reveal to students the details before they are finalised

* * *

tutor/admin

register a user for an exam

allow the user to know of the exam and keep track of the number of exam-takers

* * *

tutor/admin

deregister a user for an exam

remove entries that I made wrongly or no longer need

* * *

tutor/admin

view the lists of exams

manage the exams

* * *

tutor/admin

add a new assessments

keep track of all assessments conducted in the semester

* * *

student/tutor/admin

view a list of all assessments

know about upcoming assessments and have a record of all past ones as well

* * *

tutor/admin

add grades to a student for a particular assessment

keep track of all grades and update student about their performance

* * *

tutor/admin

add a new statistic

view general performance of students in assessments

* * *

student/tutor/admin

view a list of all statistics

know about performance of students in school examinations

* *

user

view my privilege

know what commands I have access to

* *

user

view my own details

know my details

* *

student

view my exams

know details of the exams I am going to take

* *

user

hide private contact details by default

minimize chance of someone else seeing them by accident

*

user

sort persons by name

locate a person easily

*

user

sort exams by a specified field

locate an exam easily

*

tutor

mark my student(s)s' attendance

keep track of their attendance and submit to the school

*

tutor

edit my student(s)'s attendance

correct any mistakes or make changes if any

*

tutor

view my student(s)' attendance

review and analyse my student(s)'s attendance to see if any of them require help in their work

Appendix C: Use Cases

Click to Expand

(For all use cases below, the System is the ClassRepo and the Actor is the user, unless specified otherwise)

Use case: Add person

Actors: Tutor, Admin

MSS

  1. User requests to add person.

  2. ClassRepo requests the details of the person to add.

  3. User enters the detail of the person.

  4. ClassRepo adds the person.

    Use case ends.

Extensions

  • 3a. The details entered is of an invalid format.

    • 3a1. ClassRepo shows an error message.
      Use case ends.

  • 3b. The person to add already exists in ClassRepo.

    • 3b1. ClassRepo shows an error message.
      Use case ends.

Use case: Delete person

Actors: Tutor, Admin

MSS

  1. User requests to list persons.

  2. ClassRepo shows a list of persons.

  3. User requests to delete a specific person in the list.

  4. ClassRepo deletes the person.

  5. ClassRepo checks for all the exams the person is registered for and updates the number of exam takers in the ExamBook.

  6. ClassRepo updates the exam details for all persons in the AddressBook registered for the exams.

    Use case ends.

Extensions

  • 2a. The list is empty.
    Use case ends.

  • 3a. The given index is invalid.

    • 3a1. ClassRepo shows an error message.
      Use case resumes at step 2.

Use case: Add exam

Actor: Admin

MSS

  1. User requests to add exam.

  2. ClassRepo requests the details of the exam to add.

  3. User enters the details of the exam.

  4. ClassRepo adds the exam in the ExamBook.

    Use case ends.

Extensions

  • 3a. The details entered is of an invalid format.

    • 3a1. ClassRepo shows an error message.
      Use case ends.

  • 3b. The exam to add already exists in ClassRepo.

    • 3b1. ClassRepo shows an error message.
      Use case ends.

Use case: Delete exam

Actor: Admin

MSS

  1. User requests to list exams.

  2. ClassRepo shows a list of exams.

  3. User requests to delete a specific exam in the list.

  4. ClassRepo deletes the exam in the ExamBook.

  5. ClassRepo deletes the exam for all persons registered for it in the AddressBook.

    Use case ends.

Extensions

  • 2a. The list is empty.
    Use case ends.

  • 3a. The given index is invalid.

    • 3a1. ClassRepo shows an error message.
      Use case resumes at step 2.

Use case: Edit exam

Actor: Admin

MSS

  1. User requests to list exams.

  2. ClassRepo shows a list of exams.

  3. User requests to edit a specific exam in the list.

  4. ClassRepo requests the details of the exam to edit.

  5. ClassRepo edits the exam in the ExamBook.

  6. ClassRepo edits the exam for all persons registered for it in the AddressBook.

  7. ClassRepo shows an updated list of exams in the ExamBook.

    Use case ends.

Extensions

  • 2a. The list is empty.
    Use case ends.

  • 3a. The given index is invalid.

    • 3a1. ClassRepo shows an error message.
      Use case resumes at step 2.

  • 4a. The details entered is of an invalid format.

    • 4a1. ClassRepo shows an error message.
      Use case resumes at step 2.

  • 4b. The exam with the changed details already exists in the ExamBook.

    • 4b1. ClassRepo shows an error message.
      Use case resumes at step 2.

Use case: Register for an exam

Actor: Tutor, Admin

MSS

  1. User requests to list exams.

  2. ClassRepo shows a list of exams.

  3. User requests to list persons.

  4. ClassRepo shows a list of persons.

  5. User requests to register a specific person in the person list for a specific exam in the exams list.

  6. ClassRepo edits the person.

  7. ClassRepo updates the number of exam takers for the specific exam in the ExamBook.

  8. ClassRepo updates the specific exam for all persons registered for it in the AddressBook.

  9. ClassRepo shows an updated list of exams of the specified person.

    Use case ends.

Extensions

  • 2a. The list is empty.
    Use case ends.

  • 4a. The list is empty.
    Use case ends.

  • 5a. The given person index is invalid.

    • 5a1. ClassRepo shows an error message.
      Use case resumes at step 4.

  • 5b. The given exam index is invalid.

    • 5b1. ClassRepo shows an error message.
      Use case resumes at step 4.

Use case: Deregister for an exam

Actor: Tutor, Admin

MSS

  1. User requests to list exams.

  2. ClassRepo shows a list of exams.

  3. User requests to list persons.

  4. ClassRepo shows a list of persons.

  5. User requests to deregister a specific person in the person list for a specific exam in the exams list.

  6. ClassRepo edits the person.

  7. ClassRepo updates the number of exam takers for the specific exam in the ExamBook.

  8. ClassRepo updates the specific exam for all persons registered for it in the AddressBook.

  9. ClassRepo shows an updated list of exams of the specified person.

    Use case ends.

Extensions

  • 2a. The list is empty.
    Use case ends.

  • 4a. The list is empty.
    Use case ends.

  • 5a. The given person index is invalid.

    • 5a1. ClassRepo shows an error message.
      Use case resumes at step 4.

  • 5b. The given exam index is invalid.

    • 5b1. ClassRepo shows an error message.
      Use case resumes at step 4.

Use case: Viewing the exams list

Actor: Tutor, Admin

MSS

  1. User requests to list exams.

  2. ClassRepo shows a list of exams.

    Use case ends.

Extensions

  • 2a. The list is empty.
    Use case ends.

Use case: View a person’s exams

MSS

  1. User requests to list persons.

  2. ClassRepo shows a list of persons.

  3. User requests to show exams of a specified person in the list.

  4. ClassRepo shows a list of exams of the specified person.

    Use case ends.

Extensions

  • 2a. The list is empty.
    Use case ends.

  • 3a. User is not a Tutor/Admin and is not logged in.

    • 3a1. ClassRepo shows an error message.
      Use case ends.

  • 3b. User is logged in as a Student and tries to view the exams of other students.

    • 3b1. ClassRepo shows an error message.
      Use case ends.

  • 4a. User is logged in as a Student and tries to view his own exams.

    • 4a1. ClassRepo shows a list of his non-private exams.
      Use case ends.

Use case: Add assessment

Actor: Tutor, Admin

MSS

  1. User requests to add an assessment.

  2. ClassRepo expects the name of the assessment to add.

  3. User enters the name of the assessment.

  4. ClassRepo adds the assessment to the AddressBook.

    Use case ends.

Extensions

  • 3a. The details entered are in an invalid format.

    • 3a1. ClassRepo shows an error message.
      Use case ends.

  • 3b. The assessment to add already exists in ClassRepo.

    • 3b1. ClassRepo shows an error message (duplication of assessment).
      Use case ends.

Use case: Viewing the assessments list

Actor: Student, Tutor, Admin

MSS

  1. User requests to list all assessments.

  2. ClassRepo displays an indexed list of assessments.

    Use case ends.

Extensions

  • 2a. The list is empty.
    Use case ends.

Use case: Add grades for an assessment

Actor: Tutor, Admin

MSS

  1. User requests to list persons.

  2. ClassRepo displays an indexed list of all persons in the AddressBook.

  3. User requests to list assessments.

  4. ClassRepo displays an indexed list of all assessments in the AddressBook.

  5. User requests to add grades to a specific person in the person list for a specific assessment in the assessments list.

  6. ClassRepo adds the grades to the appropriate person.

    Use case ends.

Extensions

  • 2a. The list is empty.
    Use case ends.

  • 4a. The list is empty.
    Use case ends.

  • 5a. The given person index is invalid.

    • 5a1. ClassRepo shows an error message.
      Use case resumes at step 4.

  • 5b. The given assessment index is invalid.

    • 5b1. ClassRepo shows an error message.
      Use case resumes at step 4.

  • 5c. The given grades value is invalid.

    • 5b1. ClassRepo shows an error message.
      Use case resumes at step 4.

Use case: Add statistic

Actor: Tutor, Admin

MSS

  1. User requests to list assessments.

  2. ClassRepo displays an indexed list of all assessments in the AddressBook.

  3. User requests to add a statistic for a specific assessment.

  4. ClassRepo calculates statistics for the assessment and adds it to the list

    Use case ends.

Extensions

  • 2a. The list is empty.
    Use case ends.

  • 3a. The given assessment index is invalid.

    • 3a1. ClassRepo shows an error message.
      Use case resumes at step 2.

Use case: Viewing the statistics list

Actor: Student, Tutor, Admin

MSS

  1. User requests to list all statistics.

  2. ClassRepo displays an indexed list of statistics.

    Use case ends.

Extensions

  • 2a. The list is empty.
    Use case ends.

Use case: View the user’s own details

MSS

  1. User requests to view his own details

  2. ClassRepo shows the details of the person associated with the logged-in account

    Use case ends.

Extensions

  • 1a. User is not logged in

    • 1a1. ClassRepo displays an error message.
      Use case ends.

Use case: Raise privilege to Admin

MSS

  1. User requests to increase his privilege

  2. ClassRepo requests authentication password

  3. User enters password

  4. ClassRepo increases the user’s privileges to Admin

    Use case ends.

Extensions

  • 1a. The command entered is of an invalid format

    • 1a1. ClassRepo displays an error message.
      Use case ends.

  • 3a. Incorrect password entered

    • 3a1. ClassRepo shows an error message
      Use case ends.

Use case: Change master password

Actor: Admin

MSS

  1. User requests to change the master password

  2. ClassRepo requests the current password

  3. User enters the current password

  4. ClassRepo requests the new password

  5. User enters the new password

  6. ClassRepo changes the password to the new one

    Use case ends.

Extensions

  • 3a. Incorrect password entered

    • 3a1. ClassRepo shows an error message
      User case resumes from step 2.

  • 5a. New password in the invalid format

    • 5a1. ClassRepo shows an error message
      User case resumes from step 4.

    • 5b1. The new password is the same as the old password

    • 5b2. ClassRepo shows an error message
      User case resumes from step 4.

Use case: Add account to a person

Actor: Admin

MSS

  1. User requests to list persons

  2. ClassRepo shows a list of persons

  3. User requests to add an account to a target person

  4. ClassRepo adds the account to the person

    Use case ends.

Extensions

  • 2a. The list is empty.
    Use case ends.

  • 3a. The given index is invalid.

    • 3a1. ClassRepo shows an error message.
      Use case resumes at step 2.

  • 3b. The account format is invalid.

    • 3b1. ClassRepo shows an error message.
      Use case resumes at step 2.

  • 3c. The target person has an existing account.

    • 3c1. ClassRepo shows an error message.
      Use case resumes at step 2.

Use case: Delete account

Actor: Admin

MSS

  1. User requests to list persons

  2. ClassRepo shows a list of persons

  3. User requests to delete the account belonging to a specific person in the list

  4. ClassRepo deletes the account

    Use case ends.

Extensions

  • 2a. The list is empty.
    Use case ends.

  • 3a. The given index is invalid.

    • 3a1. ClassRepo shows an error message.
      Use case resumes at step 2.

  • 3b. Target person does not have an account.

    • 3b1. ClassRepo shows an error message.
      Use case resumes at step 2.

Use case: Login to an account

MSS

  1. User requests to log in

  2. ClassRepo requests username and password

  3. User enters username and password

  4. ClassRepo logs the user into the account

    Use case ends.

Extensions

  • 3a. User provided the wrong number of arguments

    • 3a1. ClassRepo shows an error message.
      Use case ends.

  • 3b. No existing account has the given username.

    • 3b1. ClassRepo shows an error message.
      Use case ends.

  • 3c. The password does not match the existing account with the given username.

    • 3c1. ClassRepo shows an error message.
      Use case ends.

  • 4a. User is logged in.

    • 4a1. ClassRepo logs the user out before logging into the new account.
      Use case ends.

Use case: Logout of an account

MSS

  1. User requests to log out

  2. ClassRepo logs the user out of his account

    Use case ends.

Extensions

  • 2. User is not logged in

    • 2a1. ClassRepo shows an error message.
      Use case ends.

Use case: View your current privilege

MSS

  1. User requests to view his privilege

  2. ClassRepo shows the privilege level and the account the user is logged in as

    Use case ends.

Use case: Adding Fees to a Person

Actor: Admin

MSS

  1. User requests to list all the students in the address book

  2. ClassRepo shows all the current students in the console

  3. User requests to edit fees of a student to a certain value

  4. ClassRepo shows the new Fees values of the student

    Use case ends.

Extensions

  • 1a. The list is empty.

    • 1a1. ClassRepo shows that the list is empty.
      Use case ends.

  • 3a. The person to edit fees for does not exist.

    • 3a1. ClassRepo shows an error message.
      Use case ends.

Use case: Taking attendance for student

Actor: Tutor

MSS

  1. User requests to list people.

  2. ClassRepo shows a list of people.

  3. User request to update attendance of person with index x

  4. ClassRepo shows attendance of person with index x is updated

  5. User requests to change attendance of person with index x

  6. ClassRepo shows attendance of person with index x is replaced

    Use case ends.

Extensions

  • 3a. User provided the invalid index.

    • 3a1. ClassRepo shows an error message.
      Use case ends.

  • 3b. Person with index x already has attendance.

    • 3b1. ClassRepo shows an error message and suggests to use the replaceAtten command.
      Use case ends.

  • 5a. User provided the invalid index.

    • 5a1. ClassRepo shows an error message.
      Use case ends.

  • 5b. Person with index x does not have existing attendance.

    • 5b1. ClassRepo shows an error message and suggests to use attendance command.
      Use case ends.

Use case: Viewing of attendance

Actor: Tutor

MSS

  1. User requests to view attendance of person with index x

  2. ClassRepo shows attendance of person with index x

  3. User request to view attendances of people for date y

  4. ClassRepo shows the lists of people who are present and absent for date y

    Use case ends.

Extensions

  • 1a. User provided the invalid index.

    • 1a1. ClassRepo shows an error message.
      Use case ends.

  • 3a. User provided the invalid index.

    • 3a1. ClassRepo shows an error message.
      Use case ends.

  • 4b. User input invalid date.

    • 4b1. ClassRepo shows an error message.
      Use case ends.

Appendix D: Non Functional Requirements

  1. Should work on any mainstream OS as long as it has Java 9 or higher installed.

  2. Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage.

  3. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.

Appendix E: Glossary

Mainstream OS

Windows, Linux, Unix, OS-X

Private contact detail

A contact detail that is not meant to be shared with others

Private exam

An exam with details that are not meant to be released to the students yet

Privilege Level

Describes the authority of the current user. Interchangeable with the term "access level"

Main Success Scenario

The Main Success Scenario (MSS) describes the most straightforward interaction for a given use case, which assumes that nothing goes wrong.

Appendix F: Instructions for Manual Testing

Given below are instructions to test the app manually.
Before reporting bugs, refer to Known Issues to see the list of known issues that we deemed low priority to fix.

These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing.

F.1. Loading sample data

  1. Loading of sample data into the program

    1. Move the jar file into the working directory.

    2. Copy the sample data from the GitHub Repo into the working directory.

    3. Launch the jar file. Type list into the CLI to confirm that the data is loaded into the system.

F.2. Launch and Shutdown

  1. Initial launch

    1. Double-click the jar file
      Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.

The below image shows the different interactable interfaces

Interface
Figure 13. The different interfaces

F.3. Testing Privileges/Accounts

There are 3 accounts available in the sample data. Avoid modifying them to ensure smooth testing.

Person Username Password Privilege

Filbert

fil_username

fil_password

Basic

Lira

lira_username

lira_password

Tutor

John Doe

john_the_admin

pw123

Admin

The master password for the raise commamd is default_pw.

  1. Logging in

    1. Prerequisites: Not logged in.

    2. Test case: login fil_username fil_password
      viewpri
      viewself
      Expected: Login is successful. Viewpri/viewself shows correct details on both consoles.
      Other similar situations to try: Log in as a tutor/admin instead.

  2. Logging out

    1. Prerequisites: Logged in/have privilege to relinquish.

    2. Test case: logout
      viewpri
      viewself
      Expected: Logout is successful. Viewpri shows updated details on the output console. Viewself shows error on the status console.

    3. Prerequisites: Not logged in/no privilege to relinquish.

    4. Test case: logout
      Expected: Logout is unsuccessful, as shown in the status console.

  3. Raising privilege

    1. Prerequisites: Not logged in.

    2. Test case: raise default_pw
      viewpri
      Expected: Raise privilege is successful. Viewpri shows updated privileges.

  4. Accessing a command without sufficient privilege level

    1. Prerequisites: List all persons using the list command. Multiple persons in the list. Not logged in or logged in as student.

    2. Test case: delete 1
      delete 1
      Expected: No person is deleted. Error details shown in the status console. Output console remains the same.
      Other similar situations to try: Log in as a tutor instead.

  5. Accessing a command with sufficient privilege level

    1. Prerequisites: List all persons using the list command. Multiple persons in the list. Privilege is Admin, either by logging in or raising privileges.

    2. Test case: delete 1
      Expected: 1st person in the list deleted. Status console shows success message. Output console shows updated list.

    3. Test case: help
      Expected: Output console shows the list of runnable commands given the current privilege level.

    4. Other commands to try: For full list of commands testable, refer to Command Summary
      Expected: Commands execute only if the privilege level is sufficient.

F.4. Deleting an exam

  1. Deleting an exam while all exams are listed

    1. Prerequisites: List all exams using the listexams command. Multiple exams in the list. Logged in as admin.

    2. Test case: deleteexam 1
      Expected: First exam is deleted from the list. Details of the deleted exam shown in the status console. List in the output console is updated.

    3. Test case: delete 0
      Expected: No exam is deleted. Error details are shown in the status console. Output console remains the same.

    4. Other incorrect delete commands to try: deleteexam, deleteexam x (where x is larger than the list size), deleteexam a (where a is not an integer)
      Expected: Similar to previous.

    5. Other similar commands to try: delete, deleteassess
      Expected: Similar to previous.

F.5. Adding a duplicate person

  1. Add a person while it already exists in the AddressBook

    1. Prerequisites: Logged in as admin.

    2. Test case: add John Doe p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25 t/friends t/owesMoney
      Expected: Contact is added to the list. Details of the added contact shown in the status console. List in the output console is updated.

    3. Test case: add John Doe p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25 t/friends t/owesMoney after the previous test case was performed.
      Expected: No person is added. Error details are shown in the status console. Output console remains the same.

    4. Other similar commands to try: addexam, addassess
      Expected: Similar to previous.

F.6. Registering a person for an exam

  1. Register a person in the AddressBook for an exam in the ExamBook

    1. Prerequisites: List all persons using the list command. Multiple persons in the list. List all exams using the listexams command. Multiple exams in the list. Logged in as tutor/admin.

    2. Test case: regexam 1 1
      Expected: Exam is added to person. Status console shows success message. Output console displays the exams of person.

    3. Test case: regexam 1 1 after the previous test case was performed.
      Expected: Exam is not added. Error details are shown in the status console. Output console remains the same.

    4. Other similar commands to try: addassess, addstatistics
      Expected: Similar to previous.

F.7. Deregistering a person for an exam

  1. Deregister a person in the AddressBook for an exam in the ExamBook

    1. Prerequisites: List all persons using the list command. Multiple persons in the list. List all exams using the listexams command. Multiple exams in the list. Logged in as tutor/admin. Have the 1st person in the AddressBook be registered for the 1st exam in the exam book.

    2. Test case: deregexam 1 1
      Expected: Exam is removed from person. Status console shows success message. Output console displays the exams of person.

    3. Test case: deregexam 1 1 after the previous test case was performed.
      Expected: Exam is not removed. Error details are shown in the status console. Output console remains the same.

F.8. Editing an exam

  1. Edit an exam in the ExamBook and change its details

    1. Prerequisites: List all exams using the listexams command. Multiple exams in the list. Logged in as admin.

    2. Test case: editexam 1 d/07-06-2018
      Expected: Exam is edited. Status console shows success message. Output console displays the updated list of exams.

    3. Test case: editexam 1 p/y
      Expected: Exam is not edited. Error details are shown in the status console. Output console remains the same.

F.9. Viewing exams as a student

  1. View non-private exams in a student account

    1. Prerequisites: Logged in with a student account of the 1st person in the AddressBook. AddressBook has multiple persons.

    2. Test case: viewexams 1
      Expected: Status console shows success message. Output console displays the list of non-private exams of the 1st person in the AddressBook.

    3. Test case: viewexams 2
      Expected: Status console shows error message. Output console remains the same.

F.10. Editing fees for a person

  1. Editing fees for a person while all persons are listed

    1. Prerequisites: List all persons using the list command. Multiple persons in the list. Logged in as admin.

    2. Test case: editfees 1 34.50 11-12-2018
      Expected: Fees is updated for person. After the first command, status console shows success message. Output console remains the same.

    3. Test case: editfees 1 34.540 11-12-2018
      Expected: Status console shows error message. Output console remains the same.

    4. Other similar situations to try: Enter an invalid date/date format.
      Expected: Similar to previous.

F.11. Adding attendance for a person

  1. Adding attendance for a person while all persons are listed

    1. Prerequisites: List all persons using the list command. Multiple persons in the list. Logged in as tutor/admin.

    2. Test case: attendance 1 d/0 att/1
      Expected: Attendance is updated for person. Status console shows success message. Output console remains the same.

    3. Test case: attendance 1 d/0 att/1 after the previous test case was performed.
      Expected: Error details shown in the status console. Output console remains the same.

F.12. Replacing attendance for a person

  1. Updating attendance for a person while all persons are listed

    1. Prerequisites: List all persons using the list command. Multiple persons in the list. Logged in as tutor/admin. Attendance was already taken once on same date.

    2. Test case: replaceAtten 1 d/0 att/1
      Expected: Attendance is updated for person. Status console shows success message. Output console remains the same.

    3. Test case: replaceAtten 1 d/10-10-2018 att/1.
      Expected: Error details shown in the status console. Output console remains the same.

F.13. Viewing attendance for a person

  1. View the all attendance of a single person

    1. Prerequisites: List all persons using the list command. Multiple persons in the list. Logged in as tutor/admin. No attendance for the person has been taken.

    2. Test case: viewAttenPerson 1
      Expected: Person has no attendance. Status console shows success message. Output console shows nil and nil.

    3. Prerequisites: List all persons using the list command. Multiple persons in the list. Logged in as tutor/admin. Attendance for person has been taken.

    4. Test case: viewAttenPerson 1.
      Expected: Attendance is updated for person. Status console show success message. Output console shows the list of attendance.

F.14. Data storage

  1. Dealing with corrupted data files

    1. Prerequisites: Run the application at least once to generate the storage files and add in some person’s data.

    2. Open up addressbook.txt.

    3. Edit a field of a person such that it is invalid, eg. the field of phone is changed to notANumber.

    4. Run the application again.
      Expected: The application is unable to be opened. Refer to the log.txt in the base folder to check for the error message, which should indicate an error for the phone number.

    5. Other similar edits can be made to exams.txt and statistics.txt to try.
      Expected: Similar to previous.

  2. Dealing with missing data files

    1. Prerequisites: Run the application at least once to generate the storage files and add in some person and exam data. Register some persons for some exams.

    2. Delete exams.txt.

    3. Run the application again.
      Expected: The application is unable to be opened. Refer to the log.txt in the base folder to check for the error message, which should indicate an error for missing data.

    4. Other similar edits can be made to addressbook.txt to try.
      Expected: Similar to previous.