Skip to content

Latest commit

 

History

History
2197 lines (1647 loc) · 95.1 KB

DeveloperGuide.adoc

File metadata and controls

2197 lines (1647 loc) · 95.1 KB

Codeducator - Developer Guide

By: Team W09-B3      Since: Mar 2018      Licence: MIT

1. Introduction

1.1. About Codeducator

Codeducator is an open source Command Line Interface (CLI) address book and scheduling desktop application. We aim to provide a solution for private programming tutors to better manage their student contacts, tutoring schedule and track their students' learning progress.

1.2. How to Contribute

There are lots of ways to contribute to Codeducator: coding, testing or improving our build process and tools. This developer’s guide provides information that will help you get started as a Codeducator contributor. Even if you are an experienced Codeducator developer, you will still find this guide to be useful to refer to.

If you are ready to contribute, simply create a Pull Request (PR) on our main repository.

If you have found any bugs or have ideas to improve Codeducator, create an issue here or contact us directly.

2. Setting up

2.1. Prerequisites

To contribute to Codeducator, you will need the following software:

  • JDK 1.8.0_60 or later

    ℹ️
    Having any Java 8 version is not enough.
    This app will not work with earlier versions of Java 8.

    You can download the latest Java version here.

  • 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.

    You can download the latest Intellij IDE here.

2.2. Setting up the project in your computer

To set up the project in your computer, follow the steps below:

  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 dialog 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 as Project

  7. Click OK to accept the default settings

  8. Open a console and run the command gradlew processResources (Mac/Linux: ./gradlew processResources). It should finish with the BUILD SUCCESSFUL message.
    This will generate all resources required by the application and tests.

2.3. Verifying the setup

You will need to verify if your environment is set up correctly before you can start working on Codeducator.

In Intellij,

  1. Run the seedu.address.MainApp and try a few commands

  2. Run the tests to ensure they all pass.

2.4. Configurations to do before writing code

You will need to configure and set up some tools we use before you can start making meaningful contributions to Codeducator.

2.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.

2.4.2. Updating documentation to match your fork

After forking the repo, links in the documentation will still point to the se-edu/addressbook-level4 repo. If you plan to develop this as a separate product (i.e. instead of contributing to the se-edu/addressbook-level4) , you should replace the URL in the variable repoURL in DeveloperGuide.adoc and UserGuide.adoc with the URL of your fork.

2.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)

2.4.4. Getting started with coding

When you are ready to start coding,

  1. Get some sense of the overall design by reading Section 3.1, “Architecture”.

  2. Take a look at [GetStartedProgramming].

3. Design

3.1. Architecture

The Architecture Diagram given below explains the high-level design of the App. Given below is also a quick overview of each component.

Architecture
Figure 1. Architecture Diagram
💡
The .pptx files used to create diagrams in this document can be found in the diagrams folder. To update a diagram, modify the diagram in the pptx file, select the objects of the diagram, and choose Save as picture.

Main has only one class called MainApp. It is responsible for,

  • At app launch: Initializes the components in the correct sequence, and connects them up with each other.

  • At shut down: Shuts down the components and invokes cleanup method where necessary.

Commons represents a collection of classes used by multiple other components. Two of those classes play important roles at the architecture level.

  • EventsCenter : This class (written using Google’s Event Bus library) is used by components to communicate with other components using events (i.e. a form of Event Driven design)

  • LogsCenter : Used by many classes to write log messages to the App’s log file.

The rest of the App consists of 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.

Each of the four components

  • Defines its API in an interface with the same name as the Component.

  • Exposes its functionality using a {Component Name}Manager class.

For example, the Logic component (see the class diagram given below) defines it’s API in the Logic.java interface and exposes its functionality using the LogicManager.java class.

LogicClassDiagram
Figure 2. Class Diagram of the Logic Component

Events-Driven nature of the design

The Sequence Diagram below shows how the components interact for the scenario where the user issues the command delete 1.

SDforDeleteStudent
Figure 3. Component interactions for delete 1 command (part 1)
ℹ️
Note how the Model simply raises a AddressBookChangedEvent when the Address Book data are changed, instead of asking the Storage to save the updates to the hard disk.

The diagram below shows how the EventsCenter reacts to that event, which eventually results in the updates being saved to the hard disk and the status bar of the UI being updated to reflect the 'Last Updated' time.

SDforDeleteStudentEventHandling
Figure 4. Component interactions for delete 1 command (part 2)
ℹ️
Note how the event is propagated through the EventsCenter to the Storage and UI without Model having to be coupled to either of them. This is an example of how this Event Driven approach helps us reduce direct coupling between components.

The sections below give more details of each component.

3.2. UI component

UiClassDiagram
Figure 5. Structure of the UI Component

API : Ui.java

The UI consists of a MainWindow that is made up of parts e.g.CommandBox, ResultDisplay, StudentListPanel, StatusBarFooter, BrowserPanel etc. All these, including the MainWindow, inherit from the abstract UiPart class.

The UI component uses 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.

  • Binds itself to some data in the Model so that the UI can auto-update when data in the Model change.

  • Responds to events raised from various parts of the App and updates the UI accordingly.

3.3. Logic component

LogicClassDiagram
Figure 6. Structure of the Logic Component
LogicCommandClassDiagram
Figure 7. Structure of Commands in the Logic Component. This diagram shows finer details concerning XYZCommand and Command in Figure 6, “Structure of the Logic Component”

API : Logic.java

  1. Logic uses the AddressBookParser class to parse the user command.

  2. This results in a Command object which is executed by the LogicManager.

  3. The command execution can affect the Model (e.g. adding a student) and/or raise events.

  4. The result of the command execution is encapsulated as a CommandResult object which is passed back to the Ui.

Given below is the Sequence Diagram for interactions within the Logic component for the execute("delete 1") API call.

DeleteStudentSdForLogic
Figure 8. Interactions Inside the Logic Component for the delete 1 Command

3.4. Model component

ModelClassDiagram
Figure 9. Structure of the Model Component
ModelComponentDashboardClassDiagram
Figure 10. Structure of the Dashboard Class. This diagram shows finer details about the Dashboard Class.

API : Model.java

The Model,

  • stores a UserPref object that represents the user’s preferences.

  • stores the Address Book data.

  • exposes an unmodifiable ObservableList<Student> 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.

  • does not depend on any of the other three components.

3.5. Storage component

StorageClassDiagram
Figure 11. Structure of the Storage Component

API : Storage.java

The Storage component,

  • can save UserPref objects in json format and read it back.

  • can save the Address Book data in xml format and read it back.

3.6. Common classes

Classes used by multiple components are in the seedu.addressbook.commons package.

4. Implementation

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

4.1. Undo/Redo feature

4.1.1. Current Implementation

The undo/redo mechanism is facilitated by an UndoRedoStack, which resides inside LogicManager. It supports undoing and redoing of commands that modifies the state of the address book (e.g. add, edit). Such commands will inherit from UndoableCommand.

UndoRedoStack only deals with UndoableCommands. Commands that cannot be undone will inherit from Command instead. The following diagram shows the inheritance diagram for commands:

LogicCommandClassDiagram

As you can see from the diagram, UndoableCommand adds an extra layer between the abstract Command class and concrete commands that can be undone, such as the DeleteCommand. Note that extra tasks need to be done when executing a command in an undoable way, such as saving the state of the address book before execution. UndoableCommand contains the high-level algorithm for those extra tasks while the child classes implements the details of how to execute the specific command. Note that this technique of putting the high-level algorithm in the parent class and lower-level steps of the algorithm in child classes is also known as the template pattern.

Commands that are not undoable are implemented this way:

public class ListCommand extends Command {
    @Override
    public CommandResult execute() {
        // ... list logic ...
    }
}

With the extra layer, the commands that are undoable are implemented this way:

public abstract class UndoableCommand extends Command {
    @Override
    public CommandResult execute() {
        // ... undo logic ...

        executeUndoableCommand();
    }
}

public class DeleteCommand extends UndoableCommand {
    @Override
    public CommandResult executeUndoableCommand() {
        // ... delete logic ...
    }
}

Suppose that the user has just launched the application. The UndoRedoStack will be empty at the beginning.

The user executes a new UndoableCommand, delete 5, to delete the 5th student in the address book. The current state of the address book is saved before the delete 5 command executes. The delete 5 command will then be pushed onto the undoStack (the current state is saved together with the command).

UndoRedoStartingStackDiagram

As the user continues to use the program, more commands are added into the undoStack. For example, the user may execute add n/David …​ to add a new student.

UndoRedoNewCommand1StackDiagram
ℹ️
If a command fails its execution, it will not be pushed to the UndoRedoStack at all.

The user now decides that adding the student was a mistake, and decides to undo that action using undo.

We will pop the most recent command out of the undoStack and push it back to the redoStack. We will restore the address book to the state before the add command executed.

UndoRedoExecuteUndoStackDiagram
ℹ️
If the undoStack is empty, then there are no other commands left to be undone, and an Exception will be thrown when popping the undoStack.

The following sequence diagram shows how the undo operation works:

UndoRedoSequenceDiagram

The redo does the exact opposite (pops from redoStack, push to undoStack, and restores the address book to the state after the command is executed).

ℹ️
If the redoStack is empty, then there are no other commands left to be redone, and an Exception will be thrown when popping the redoStack.

The user now decides to execute a new command, clear. As before, clear will be pushed into the undoStack. This time the redoStack is no longer empty. It will be purged as it no longer make sense to redo the add n/David command (this is the behavior that most modern desktop applications follow).

UndoRedoNewCommand2StackDiagram

Commands that are not undoable are not added into the undoStack. For example, list, which inherits from Command rather than UndoableCommand, will not be added after execution:

UndoRedoNewCommand3StackDiagram

The following activity diagram summarize what happens inside the UndoRedoStack when a user executes a new command:

UndoRedoActivityDiagram

4.1.2. Design Considerations

Aspect Alternatives Pros (+)/ Cons(-)

Implementation of UndoableCommand

Add a new abstract method executeUndoableCommand() (current choice)

+ : We will not lose any undone/redone functionality as it is now part of the default behaviour. Classes that deal with Command do not have to know that executeUndoableCommand() exist.

- : Hard for new developers to understand the template pattern.

Just override execute()

+ : Does not involve the template pattern, easier for new developers to understand.

- : Classes that inherit from UndoableCommand must remember to call super.execute(), or lose the ability to undo/redo.

How undo & redo executes

Saves the entire address book. (current choice):

+ : Easy to implement.

- : May have performance issues in terms of memory usage.

Individual command knows how to undo/redo by itself.

+ : Will use less memory (e.g. for delete, just save the student being deleted).

- : We must ensure that the implementation of each individual command are correct.

Type of commands that can be undone/redone

Additional Info:** See our discussion here.

Only include commands that modifies the address book (add, clear, edit). (current choice):

+ : We only revert changes that are hard to change back (the view can easily be re-modified as no data are * lost).

- : User might think that undo also applies when the list is modified (undoing filtering for example), * only to realize that it does not do that, after executing undo.

Include all commands.

+ : Might be more intuitive for the user.

- : User have no way of skipping such commands if he or she just want to reset the state of the address * book and not the view.

Data structure to support the undo/redo commands

Use separate stack for undo and redo (current choice)

+ : Easy to understand for new Computer Science student undergraduates to understand, who are likely to be * the new incoming developers of our project. - : Logic is duplicated twice. For example, when a new command is executed, we must remember to update * both HistoryManager and UndoRedoStack.

Use HistoryManager for undo/redo

+ : We do not need to maintain a separate stack, and just reuse what is already in the codebase.

- : Requires dealing with commands that have already been undone: We must remember to skip these commands. Violates Single Responsibility Principle and Separation of Concerns as HistoryManager now needs to do two * different things.

4.2. Logging

We are using java.util.logging package for logging. The LogsCenter class is used to manage the logging levels and logging destinations.

  • The logging level can be controlled using the logLevel setting in the configuration file (See Section 4.3, “Configuration”)

  • The Logger for a class can be obtained using LogsCenter.getLogger(Class) which will log messages according to the specified logging level

  • Currently log messages are output through: Console and to a .log file.

Logging Levels

  • SEVERE : Critical problem detected which may possibly cause the termination of the application

  • WARNING : Can continue, but with caution

  • INFO : Information showing the noteworthy actions by the App

  • FINE : Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size

4.3. Configuration

Certain properties of the application can be controlled (e.g App name, logging level) through the configuration file (default: config.json).

4.4. [Proposed] Data Encryption

A password must be implemented, used as secret key. Using Java Cryptography Extension (JCE) library, we can encrypt text in the xml files.
First we save as XML files, then we encrypt the text data in the XML to encrypted text, storing it somewhere, then deleting the XML file.
The reverse process is decrypting the encrypted data to XML, then reading data from there.

5. Features Implementation

5.1. Favourites feature

The favourites feature allows users to remember/mark a student by adding them to favourites.

5.1.1. Current Implementation

To facilitate the favourite/unfavourite feature, an association with a new Favourite class is added to the Student class:

StudentWithPLFeature
Figure 12. Structure of the atrributes of a Student in the Model component. The diagram shows that the Student class is associated with the Favourite class.

Since the implementation of the favourite and unfavourite command are similar, we will describe the implementation of the favourite command only.

The following sequence diagram shows how the favourite command works:

FavouriteCommandSequenceDiagram
Figure 13. Sequence diagram for the favourite command
  1. The FavouriteCommandParser parses the user input to obtain the target student index and constructs a new FavouriteCommand with this index.

  2. The logic portion of the favourite command will be executed by the FavouriteCommand class. To mark a Student object called "studentToFavourite" as favourite:

    1. The preprocessUndoableCommand() method calls setTargetStudent() which will set the "studentToFavourite" object based on the provided student index.

    2. preprocessUndoableCommand() will then call the createEditedStudent() method which will create a Student object called "editedStudent". "editedStudent" will have the attributes of "studentToFavourite", except that its Favourite attribute will be set to "true".
      createEditedStudent() is implemented as such:

    private void createEditedStudent() {
        assert targetStudent != null;
        editedStudent = new StudentBuilder(target).withFavourite(true).build();
    }
  1. In the executeUndoableCommand() method, Model.updateStudent(Student, Student) is called to replace "studentToFavourite" with "editedStudent" in the Address Book in-memory.

5.1.2. Design Considerations

Aspect Alternatives Pros (+)/ Cons(-)

Implementation of 'FavouriteCommand'

Add a Favourite attribute to Student (current choice)

+ : It is easy to mark a student as favourite since we can make use of the current Model.updateStudent(Student, Student) method by creating a copy of the target Student object, with the value of its Favourite attribute set to "true"

- : Creating a copy of the Student object can be inefficient

Create a new UniqueFavouriteStudentsList that contains the list of students in favourites and store this list in the Address Book

+ : Students that are currently in favourites can be managed more easily since there is a direct overview of which student is in favourites

- : Students in the UniqueFavouriteStudentsList have to be synced with the UniqueStudentsList. For example, we have to ensure that deleting a student in the UniqueStudentList deletes the student in the UniqueFavouriteStudentsList too

5.2. Location feature

Selecting a student using the select command will render their location on google maps.

5.2.1. Current Implementation

The address of the student is extracted and converted in a string to be appended to the end of the SEARCH_PAGE_URL in the following function

    private void loadStudentPage(Student student) {
        Address location = student.getAddress();
        String append = location.urlstyle();
        loadPage(SEARCH_PAGE_URL + append);
    }

An example is provided below when select 1 is entered as a command:

location ss

5.2.2. Design Considerations

Aspect Alternatives Pros (+)/ Cons(-)

Implementation of displaying student locations

Display it on the embedded browser (current choice)

+ : Easy to implement, simply alter the default webpage

- : Might not be able to display student information and location simultaneously

Creating a new window to display the location

+ : This would allow concurrent display of locations of many students

- : the UI would be messy and user has to navigate between 2 different windows

5.3. Programming Language Feature

The programmingLanguage field is part of the student model and helps to keep track of what programming language he/she is being taught with.

5.3.1. Current Implementation

The programming language feature involves having an additional class to the student model called ProgrammingLanguage. It stores the name of the programming language currently being taught to each student as a string.

ℹ️
The string for ProgrammingLanguage must contain visible characters.
StudentWithPLFeature

As can be seen from the diagram, the field ProgrammingLanuage has been added to the student model.

Concerning the Logic component, when the add command or edit command is called, a Student object with attributes including ProgrammingLanguage will be created/edited depending on which command was entered.

For example, adding a student would have the command string parsed for arguments in such a way:

    public AddCommand parse(String args) throws ParseException {
        // ...Tokenize the String Input...
        // ...Check if prefixes are present...
        try {
            // ...Parses the other fields required of a Student...
            ProgrammingLanguage programmingLanguage = ParserUtil.parseSubject(argMultimap
                    .getValue(PREFIX_PROGRAMMING_LANGUAGE)).get();
            Student student = new Student(name, phone, email, address, programmingLanguage, tagList);
            return new AddCommand(student);
		} catch (IllegalValueException ive) {
            throw new ParseException(ive.getMessage(), ive);
        }
	}

A new student would then be added. On the other hand, editing a student’s programming language will be done by creating an edited student in such a way:

	private static Student createEditedStudent(Student studentToEdit, EditStudentDescriptor editStudentDescriptor) {
        assert studentToEdit != null;
        // ...Set other attributes of the prospective newly edited student...
        ProgrammingLanguage updatedProgrammingLanguage = editStudentDescriptor.getProgrammingLanguage();
        return new Student(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedProgrammingLanguage,
                updatedTags);
    }

The editedStudent will have the new programming language attribute and will hence be used to replace in the Address Book in-memory.

5.3.2. Design Considerations

Aspect Alternatives Pros (+)/ Cons(-)

How to store ProgrammingLanguage for a Student

Store as an attribute of Student. (current choice)

+ : Easy to keep track of as well as modify.

- : Coupling increases as more classes (ProgrammingLanguage and Student) are associated with each other.

Store as a separate list and have each student index in the UniqueStudentsList be mapped to each item in the list.

+ : Less coupling so less need to refactor code

- : Might be messier to implement, especially if the UniqueStudentsList have it’s students swapping indexes.

What command to add ProgrammingLanguage to Student

Implement it through the existing add command. (current choice)

+ : Intuitive and the user does not have to learn an additional command

- : User will have to type a longer string for add command to include the programming language used by the student.

Implement it as a new command.

+ : User will be able to add or modify ProgrammingLanguage one or possibly even a few students at their own discretion.

- : User will have to learn a new specific command and might also be slightly difficult to implement.

5.4. Profile Page feature

The profile page feature allows the user to view the full information of contacts(students) kept in their data. This page has each student’s main info, miscellaneous info, and their profle picture.

5.4.1. Current Implementation

Users will also be able to edit the miscellaneous information of a student as well as his/her profile picture. The profile picture is changed by providing a file path to the actual picture file.

ℹ️
The picture file to be changed to must be a valid and existing file with extensions of .png or .jpg

The following diagram shows the student model including the primary attributes as well as the miscellaneous information attributes.

StudentWithMiscInfoDiagram

When a student is added by the addCommand, the MiscellaneousInfo and ProfilePicturePath of the student will be set to these default values:

  • Allergies, NextOfKinName, Remarks will be set to Not updated.

  • NextOfKinPhone will be set to 000.

  • ProfilePicturePath will be set to the path of a profile photo placeholder within the app.

This feature revolves mainly around 3 commands:

  1. moreInfo : Shows the actual profile page on the web browser.

  2. editMisc : Edits the miscellaneous information of a student.

  3. editPicture : Edits the profile picture of a student with a valid picture file(refer to note above). The user will have to provide the filepath to this file. moreInfo Command

For the command moreInfo, the model manager calls upon the data storage (addressbook) to raise an event for the Browser Panel to display the profile page of a student.

⚠️
The moreInfo command cannot function if there is no real existing XML data of students. Thus, the sample student data provided at the initial start up will not work with this command. A warning will be mentioned if the command is called without existing data.

The code below shows how the the method is called with the parameter of the required Student functions:

	public void displayStudentDetailsOnBrowserPanel(Student target) throws StudentNotFoundException,
            StorageFileMissingException {
        addressBook.checkForStudentInAddressBook(target);
        checkIfStorageFileExists();
        indicateRequiredStudentIndexChange(filteredStudents.indexOf(target));
        indicateBrowserPanelToDisplayStudent(target);
    }

The method checkIfStorageFileExists() checks if there is any real XML data of students at the moment. If none exists, then an exception is thrown and the command will not perform (as mentioned in the note above). The method indicateRequiredStudentIndexChange(Index indexOfStudent) calls the modifying of XML data of which student is needed to display his/her profile page. This is because the HTML files can only read data from XML files and hence, an external XML file containing the index of the student whose profile page is required to be shown is needed.

Lastly, indicating the browser panel to display a student will raise a StudentInfoDisplayEvent which is handled in the BrowserPanel with the following code:

	private void handleStudentInfoDisplayEvent(StudentInfoDisplayEvent event) {
		//... logging process...
		loadStudentInfoPage();
		//... raising event to switch panels...
	}

The diagram below shows how the event is handled in the BrowserPanel :

width:400

editMisc Command

For the command editMisc, this is similar to the edit function, except it takes on different optional parameters. These are [ALLERGIES], [NEXTOFKINNAME], [NEXTOFKINPHONE], [REMARKS]. The code snippet below shows how the studentToEdit is created when the editMisc command is called.

	private static Student createEditedStudent(Student studentToEdit, EditMiscDescriptor editMiscDescriptor) {
		assert studentToEdit != null;
		//... main information of the student is copied over...
		Allergies allergies = editMiscDescriptor.getAllergies()
				.orElse(studentToEdit.getMiscellaneousInfo().getAllergies());
		NextOfKinName nextOfKinName = editMiscDescriptor.getNextOfKinName()
				.orElse(studentToEdit.getMiscellaneousInfo().getNextOfKinName());
		NextOfKinPhone nextOfKinPhone = editMiscDescriptor.getNextOfKinPhone()
				.orElse(studentToEdit.getMiscellaneousInfo().getNextOfKinPhone());
		Remarks remarks = editMiscDescriptor.getRemarks()
				.orElse(studentToEdit.getMiscellaneousInfo().getRemarks());
		MiscellaneousInfo miscellaneousInfo = new MiscellaneousInfo(allergies, nextOfKinName, nextOfKinPhone, remarks);

		return new Student(uniqueKey, name, phone, email, address,
				programmingLanguage, tags, isFavourite, dashboard, profilePicturePath, miscellaneousInfo);
}

After that, the student will be updated with the new details for his/her miscellaneous information.

editPicture Command

For the command editPicture, the student’s index will have to be provided by the user again. The next parameter for this is the required file path of the picture file. This can be in the form of an absolute file path (starting from a hardrive like C:/Users/…​/picture.png) or relative to the folder that the jar application is in.

This command uses the similar method of the edit command and the editMisc command where a new Student with the edited details is created to overwrite the current existing student. In this case, the ProfilePicturePath of the student is edited. When this command is called, a ProfilePictureChangeEvent will be raised and the Storage Manager will call a method to save the data of the profile picture from its original location to a location in the jar folder.

The code below shows how the saving of the file is done:

	public void saveProfilePicture(ProfilePicturePath pathToChangeTo, Student student) throws IOException {
		//... ensuring that the picture's filepath exists
		//... getting the extension of the provided filepath of the picture
		deleteExistingProfilePicture(studentPictureFilePath);
		Path studentPictureFilePathWithExtension = Paths.get(studentPictureFilePath.toString() + extension);
		logger.fine("Attempting to write to data file: data/" + student.getUniqueKey().toString());
		Files.copy(newPath, studentPictureFilePathWithExtension);
    }

Thus, the HTML file for displaying the student’s profile page will be able to show the new image, which is copied to the local jar folder.

The following sequence diagram illustrates the process of calling the editPicture command.

width:600
Figure 14. Sequence diagram showing the important details of the process of the editPicture command

As seen from the above diagram, the createFinalEditedStudent() method ensures that the correct profile picture path is saved onto the student’s XML data in order to be read by the HTML file which displays the student profile page. The method createEditedStudent creates the student wi

5.4.2. Design Considerations

Aspect Alternatives Pros (+)/ Cons(-)

Displaying and styling the profile page of a student

*Have it as a JavaScript function in the HTML file of the student’s profile page.

+ Able to directly read the XML data of students from the file. (current choice)*

- Have to export the required files and folder out of the jar file as the JavaScript is unable to retrieve files outside of the Jar folder.

Have it as a JavaFX file.

+ : Able to read the student’s data from the UniqueStudentList.

- : Might be more difficult and messy to implement in code.

Editing the profile picture

Copy the picture file into the local jar directory. (current choice)

+ : Ensures that the picture can still be loaded even when the original picture file is deleted.

- Requires more code to copy the files over and ensure their validity

Read from the direct location of the original picture file.

+ : Less code of copying is required and any modifications to the original photo is immediately updated.

- : If the picture is deleted or corrupted, the profile picture would not be able to display.

5.5. Schedule feature

5.5.1. Current Implementation

To get better control of one’s weekly schedule, we will now attach a component called Schedule to Model.

At startup, a new Schedule object is instantiated in ModelManager.

A Schedule has a LessonList, it contains an ObservableList<Lesson> internalList attribute, which stores all the Lesson objects that describes your schedule. The UI is bounded to this LessonList so that it can automatically update when data changes.

A Lesson has a UniqueKey attribute, a Day attribute, a starting TIME START_TIME and an ending TIME END_TIME attribute. Lesson objects are created by the addLesson command.

LessonClassDiagram
Implementation of commands that edit your Schedule

Commands that modify the schedule are addLesson and deleteLesson. Editing a student’s name will edit the name of the event in the schedule. Deleting a student will also delete all his lessons in the schedule.

  • Students have the UniqueKey field, which we will now use in Lesson to create a relation to Student objects.

  • A Lesson object called newLesson will be created by ModelManager.addLesson(UniqueKey key, Day day, Time startTime, Time endTime), which is implemented as such:

    public void addLesson(Student studentToAddLesson, Day day, Time startTime, Time endTime) {
        requireAllNonNull(studentToAddLesson, day, startTime, endTime);
        UniqueKey studentKey = studentToAddLesson.getUniqueKey();
        Lesson newLesson = new Lesson(studentKey, day, startTime, endTime);
        schedule.addLesson(newLesson);
        indicateScheduleChanged();
    }

A sequence diagram of the result can be seen from the below diagram.

AddLessonSequenceDiagram
Figure 15. Sequence Diagram of addLesson command

The student will be selected by the Index of the last seen list of students. The UniqueKey is then retrieved from the Student. A new Lesson will now be added for that student at the specific Day, startTime and endTime, associated with the Student by the key

No Lesson objects can be created for students not in contact list.

ℹ️
If you have a future implementation that requires the addition of a new attribute in the Schedule class, you must take note of updating the Model.addLesson(Student, Day, Time START_TIME, Time END_TIME) method to reflect the new attribute.
Implementation of viewing your Schedule

The schedule command displays of a student’s dashboard. The schedule command is implemented this way:

ScheduleCommandSequenceDiagram
Figure 16. Sequence Diagram of schedule command

From the following diagram,

  1. InfoPanel handles the showScheduleEvent event. It changes the view to the CalendarPanel, hiding DashboardPanel and BrowserPanel.

  2. InfoPanel raises the showScheduleEvent which is also handled by CalendarPanel to display the lessons of the student in the schedule.

5.5.2. Design Considerations

Aspect Alternatives Pros (+)/ Cons(-)

Implementation of Lesson in Schedule

Schedule contains Lesson objects, schedule is made up of only one layer, with attributes directly attached to Lesson (current choice)

+ : It is easier implement, just add Lesson to a Schedule, which is a list of Lessons

- : Results in more coupling, attributes could have been furthur separated out. It is inefficient to search by Day. Searching for empty slot requires linear searching.

Lesson contains two layers of classes, Day is attached to Schedule and Lesson is attached to Day

+ : Less coupling and more cohesive design

- : Much harder to implement and gets overly complicated

Data structure of Schedule

Relational database related by a uniquekey attribute (current choice)

+ : Much better normalised design. Modifying contacts list in any way will not affect the Schedule database.

- : Another layer of abstraction. Harder to implement

Adding Student objects to lessons in schedule

+ : Easier implementation.

- : Changes in contacts list data will require more workarounds to modify schedule data.

5.6. Google Service Integration

To sync with Google Contacts and Google Calendar, a GServiceManager class is implemented to handle the 2 services. GServiceManager contains a GContactsService and GCalendarService objects. GServiceManager.synchronize calls GContactsService.synchronize and GCalendarService.synchronize

5.6.1. Prerequisites/Dependencies

Google Contacts and Calendar APIs require an external libaries. Remember to add the following to your dependencies

dependencies {
    compile 'com.google.api-client:google-api-client:1.23.0'
    compile 'com.google.oauth-client:google-oauth-client-jetty:1.23.0'
    compile 'com.google.apis:google-api-services-oauth2:v1-rev139-1.23.0'
    compile 'com.google.apis:google-api-services-calendar:v3-rev305-1.23.0'
    compile group: 'com.google.gdata', name: 'core', version: '1.47.1'
}

5.6.2. Design Considerations

Aspect Alternatives Pros (+)/ Cons(-)

Implementation of GServiceManager class

Separate out 2 Google Services into two classes (current choice)

+ : Less coupling

- : More files and more code

All services are in GServiceManager class. Synchronize runs the upload for both Contacts and Calendar classes.

+ : Fewer files and code to read

- : More coupling

Implementation of flow of data for a sync

Only Upload (current choice)

As we have to store the IDs of contacts and events created offline, that would create a massive database issue. + : Reduces the complexity of the implementation of syncing data.
+ - : User cannot download updated data that he synced from another Codeducator instance

Upload and download

+ : Much more convenient for the user to sync his data to the cloud.

- : Much harder to implement. At every session, need to keep track of which users were edited, added or deleted (similar to a diff program)

5.7. Dashboard feature

The dashboard feature aims to help users keep track of their students' learning progress.

5.7.1. Current Implementation

To have a dashboard for each student, an association with a new Dashboard class is added to the Student class. We have also created new classes associated with the Dashboard class to facilitate the different capabilities of the dashboard. The following diagram shows the class diagram of the components that facilitate the dashboard feature:

ModelComponentDashboardClassDiagram
Figure 17. Class diagram of the components that facilitate the dashboard feature

Both UniqueMilestoneList and UniqueTaskList contain an attribute called "internalList" which are ObservableList<Milestone> and ObservableList<Task> respectively. This means that the UI can be bound to both of the lists so that it can automatically update when the data in any of the lists change.

A new Dashboard object is created every time a new Student is being created. The Dashboard object will contain an empty milestone list until the user adds new milestones to the dashboard. This enforces 1-to-1 association between Student and Dashboard, as well as between Dashboard and UniqueMilestoneList.

For example, the constructor for Student is implemented this way:

    public Student(Name name, Phone phone, Email email, Address address, ProgrammingLanguage programmingLanguage, Set<Tag> tags) {
        requireAllNonNull(name, phone, email, address, tags);
        this.name = name;
        this.phone = phone;
        // ... initialise the rest of the attributes ...
        this.dashboard = new Dashboard();
    }

The constructor for Dashboard is implemented this way:

    public Dashboard() {
        milestoneList = new UniqueMilestoneList();
    }
Implementation for commands that modify the Dashboard

The AddMilestoneCommand, AddTaskCommand, CheckTaskCommand and ShowDashboardCommand commands facilitate operations to the dashboard. A common implementation for commands that modify the dashboard (e.g. AddMilestoneCommand) is that a new copy of Dashboard is created with the new modification.

For example, in the AddMilestoneCommand, to add a new milestone object to the dashboard of a Student Object called "targetStudent":

  1. AddMilestoneCommand.preprocessUndoableCommand() calls the AddMilestoneCommand.createEditedStudent() method which will create a Student object called "editedStudent". "editedStudent" is created with the same attributes of "targetStudent", but with a new Dashboard object containing the new milestone.
    AddMilestoneCommand.createEditedStudent() is implemented as such:

    private void createEditedStudent() throws DuplicateMilestoneException {
        requireAllNonNull(studentToEdit, newMilestone);
        editedStudent = new StudentBuilder(targetStudent).withNewMilestone(newMilestone).build();
    }
  1. In the AddMilestoneCommand.executeUndoableCommand() method, Model.updateStudent(Student, Student) is called to replace "targetStudent" with "editedStudent" in the Address Book in-memory.

Implementation for displaying the dashboard

The ShowDashboardCommand facilitates the displaying of a student’s dashboard. The ShowDashboardCommand.execute() method is implemented this way:

    public CommandResult execute() throws CommandException {
        // ... check whether targetIndex is valid ...
        EventsCenter.getInstance().post(new ShowStudentDashboardEvent(lastShownList.get(targetIndex.getZeroBased())));
        // ... return command result ...
    }

As seen from the above code snippet, ShowDashboardCommand.execute() raises a ShowStudentDashboardEvent. The sequence diagram below shows how the EventsCenter reacts to that event.

ShowDashboardCommandSequenceDiagram
Figure 18. Sequence diagram showing how the the EventsCenter and the Ui components react to the ShowDashboardCommand

As seen from the above diagram,

  1. InfoPanel handles the ShowStudentInDashboard event.

  2. InfoPanel then raises the ShowStudentNameInDashboard which is handled by DashboardPanel to display the name of the student in the dashboard.

  3. Finally, InfoPanel raises the ShowMilestoneEvent which is also handled by DashboardPanel to display the milestones of the student in the dashboard.

5.7.2. Design Considerations

Aspect Alternatives Pros (+)/ Cons(-)

Aspect: Data structure to support the dashboard feature

Add a Dashboard association to Student (current choice)

+ : Able to access the dashboard of a student easily.

- : Since Student is immutable, a new Student object has to be created each time its Dashboard is modified.

Add a new UniqueDashboardList association to AddressBook

+ : Able to modify the dashboard easily if it is not made immutable.

- : We will have to sync the UniqueDashboardList with the UniqueStudentList since Dashboard will be associated to a Student.

5.8. Natural Language Processing capabilities

Allows users to invoke features using free-form english, apart from keywords specific to each feature.

5.8.1. Current implementation

An AI bot(agent) that is trained to process sentences based on the features integrated is into the application. Its primary goal is to identify the user’s intention of the input and match it with a corresponding feature which the user wishes to use.

A new class ConversationCommand is written to process sentences that do not match the syntax of any features.

Making API calls via the REST API

The method below, written using the IBM Watson™ Assistant service API, is used to make the API call to the agent. The userInput field contains the sentence that the user inputs.

    public static MessageResponse getMessageResponse(String userInput) {
        MessageResponse response = null;

        InputData input = new InputData.Builder(userInput).build();
        MessageOptions option = new MessageOptions.Builder("19f7b6f4-7944-419d-83a0-6bf9837ec333").input(input).build();
        response = service.message(option).execute();

        return response;
    }
Intents and Entities

Intents refers to the intention behind the input of the user and entities refer to objects of interest e.g. name, address, location

The agent is integrated into the AddressBookParser class and the following code snippet deciphers the intents and the entity embedded in the user’s input.

            //processes the userInput
            response = ConversationCommand.getMessageResponse(userInput);
            intents = response.getIntents();
            entities = response.getEntities();

            for (int i = 0; i < intents.size(); i++) {
                intention = intents.get(i).getIntent();
            }

            if (entities.size() != 0) {
                for (int i = 0; i < intents.size(); i++) {
                    entity = entities.get(i).getValue();
                }
            }
Important
Every single input always has an intent, but that is not the case for entities!

For further clarification, refer to the screenshot below:

debug message
Figure 19. Example of an intention and an entity, with its corresponding value. The intention is Select and the entity refers to the name of a person, which takes on a value of Jason in this particular case.
Matching the desired command

After identifying the intent and entities (if present) in the user’s input, the corresponding features matching intent is called, passing any entities as parameters to the feature’s method.

Select(after)
Figure 20. Following the example in Figure 12, the select command is invoked, passing Jason as a parameter, after the intent and entity is identified.

5.8.2. Design Consideration

Aspect Alternatives Pros (+)/ Cons(-)

Aspect: Selection of an appropriate third-party APIs to implement NLP

IBM Watson™ Assistant service (current choice)

+ : Offers extensive NLP functions which are easy to implement. User-friendly interface allows ease of training of the model, which has high scalability

- : Lite version offers a limited number of API calls per month (10,000).

Stanford CoreNLP

+ : Possesses a powerful and comprehensive API, comprising of a set of stable and well-tested natural language processing tools, widely used by various groups in academia, industry, and government.

- : Highly modularised and requires in-depth knowledge of Machine-learning and Deep-learning to use effectively.

Google Cloud Natural Language

+ : Offers a variety of functions (Syntax Analysis, Entity Recognition, Sentiment Analysis etc.) and integrates REST API, powerful enough to analyse texts properly and texts can be uploaded in the request or integrated with Google Cloud Storage.

- : Difficult to implement and integrate properly into the application

6. 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.

6.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.

6.2. Publishing Documentation

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

6.3. Converting Documentation to PDF format

We use Google Chrome for converting documentation to PDF format, as Chrome’s PDF engine preserves hyperlinks used in webpages.

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 21. Saving documentation as PDF files in Chrome

7. Testing

7.1. Running Tests

There are three ways to run tests.

💡
The most reliable way to run tests is the 3rd one. The first two methods might fail some GUI tests due to platform/resolution-specific idiosyncrasies.

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 allTests (Mac/Linux: ./gradlew clean allTests)

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

Method 3: Using Gradle (headless)

Thanks to the TestFX library we use, our GUI tests can be run in the headless mode. In the headless mode, GUI tests do not show up on the screen. That means the developer can do other things on the Computer while the tests are running.

To run tests in headless mode, open a console and run the command gradlew clean headless allTests (Mac/Linux: ./gradlew clean headless allTests)

7.2. Types of tests

We have two types of tests:

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

    1. System Tests that test the entire App by simulating user actions on the GUI. These are in the systemtests package.

    2. Unit tests that test the individual components. These are in seedu.address.ui package.

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

    1. Unit tests targeting the lowest level methods/classes.
      e.g. seedu.address.commons.StringUtilTest

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

    3. Hybrids of unit and integration tests. These test are checking multiple code units as well as how the are connected together.
      e.g. seedu.address.logic.LogicManagerTest

7.3. Troubleshooting Testing

Problem: HelpWindowTest fails with a NullPointerException.

  • Reason: One of its dependencies, UserGuide.html in src/main/resources/docs is missing.

  • Solution: Execute Gradle task processResources.

8. Dev Ops

8.1. Build Automation

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

8.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.

8.3. Coverage Reporting

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

8.4. Documentation Previews

When a pull request has changes 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.

8.5. Making a Release

Here are the steps to create a new release.

  1. Update the version number in MainApp.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.

8.6. Managing Dependencies

A project often depends on third-party libraries. For example, Address Book 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)

9. Product Scope

Target user profile:

  • has a need to plan tuition slots for large number of students

  • wants to store students' profile information and pictures

  • wants to keep a progress log for students

  • is able to reference common important student details like contact number

  • prefer desktop apps over other types

  • can type fast

  • prefers typing over mouse input

  • is reasonably comfortable using CLI apps

Value proposition: improve the planning process for scheduling time slots for all tutees

9.1. Feature Contribution

Samuel Loh:

  • (Minor) Added programmingLanguage field to student model and modified add/edit commands to fit enhancement

    • This helps the tutor to identify what programming language is being used by each student to learn coding.

  • (Major) Create a profile page storing other important details of the students including a profile picture.

    • This helps the tutor store more information about students, which are not referenced as often, in another portion and thus are not displayed on the student card. E.g. Next of kin contact and an optional profile picture

Tan Wei Hao:

  • (Minor) Added a findTag command

    • This allows the tutor to find a student by tag labels.

  • (Major) Syncing timetable with Google calendar

    • This helps the tutor keep track of lessons better by syncing with his Google calendar. It also allows the use of Google calendar features.

Tan Chee Wee:

  • (Minor) Selecting a student via 'select' commands renders their location on google maps

    • This allows the tutor to easily plan a route to the student’s home.

  • (Major) Add a functionality that enables tutor to use free-form english to execute commands instead of conforming to the specific syntax

    • This makes the app more user-friendly without the need to memorise the syntax of respective commands and able to execute them more intuitively.

Yap Ni:

  • (Minor) Favourites feature where tutors can add or remove students from favourites and list students that are in their favourites

    • This helps the tutor to remember or view the list of prominent students they want to take note of easily.

  • (Major) Dashboard feature where each student has their own dashboard

    • This helps the tutor to better plan out lessons for each student and track their learning progress.

Appendix A: User Stories

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

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

* * *

tutor

add a new student

* * *

tutor

be able to edit the miscellaneous information of a student

have the most updated version of a student’s information

* * *

tutor

delete a student

remove entries that I no longer need

* * *

tutor

find a student by name

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

* * *

tutor

find a student by programming language

locate details of students of a certain programming language

* * *

new user

see usage instructions

refer to instructions when I forget how to use the App

* * *

tutor

search a student by label/tag

so I can easily categorize my students as per my personal preferences

* * *

tutor

indicate a student’s programming language when adding one

so I can know which programming language to prepare before my lesson

* * *

tutor

view the address of a student in the maps

know where the student lives

* * *

tutor

add a student to favourites

keep track of that student

* * *

tutor

list students added to favourites

view students I’m keeping tack

* * *

tutor

upload my contacts to Google Contacts

sync my contacts list with Google Contacts, being able to easily view my data across devices

* * *

tutor

be able to view misc info of my students on a different page

have an easier viewing of them

* * *

tutor

view the profile pictures of each student(if it exists)

learn to recognise them

* * *

tutor

be able to add/change a profile picture for my students

* * *

tutor

have a remarks column included in the misc info for each student

add specific remarks for each particular student that may be important to note

* * *

tutor

view timetable of lessons by week

easily view my schedule

* * *

tutor

add a lesson for a student

* * *

tutor

delete a lesson for a student

remove lessons that the student cancels

* *

tutor who adds lessons in odd hours(very early or very late)

see my schedule resize

can view my lessons in full and have a better user experience.

* *

tutor

check free slot

easily find a free timeslot to allocate to students

*

tutor

edit a lesson for a student

make changes to lessons when required

* * *

tutor

upload my lessons to Google Calendars

easily sync my schedule with Google Calendars, being able to view them across all my devices

* * *

tutor

get an overview of my student’s progress

can see what they don’t know and tutor them better

* * *

tutor

type little but get the command I want

to save time

* *

tutor

sort the contact list by programming language

easily recognise which and how many students are taking a particular programming language

*

tutor

send emails to my student

to send reminders for upcoming lessons or payments owed

*

tutor

submit feedback to the developers

to improve my user experience

*

tutor with many students in the address book

sort students by name

locate a student easily

Appendix B: Use Cases

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

Use case: Delete student

MSS

  1. User requests to list students

  2. Codeducator shows a list of students

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

  4. Schedule deletes the student

    Use case ends.

Extensions

  • 2a. The list is empty.

    Use case ends.

  • 3a. The given index is invalid.

    • 3a1. Codeducator shows an error message.

      Use case resumes at step 2.

Use case: Adding a lesson

MSS

  1. Schedule panel shows lessons and timeslots

  2. User requests to add a lesson

  3. Codeducator adds that lesson to that slot

    Use case ends.

Extensions

  • 2a. The schedule is empty.

    Use case ends.

  • 2b. The schedule is full. (Any attempt to add lessons will result in clashes)

    • 3b1. Codeducator shows an error message.

  • 3a. The given student index is invalid.

    • 3a1. Codeducator shows an error message.

      Use case resumes at step 2.

Use Case: View a student’s profile page

MSS

  1. User requests to list students.

  2. Student list panel shows a list of students.

  3. User requests to view profile page of a student.

  4. Browser panel shows profile page of student.

    Use case ends.

Extensions

  • 2a. The list is empty.

    Use case ends.

  • 3a. The given index is invalid.

    • 3a1. Error message shown.

    • 3a2. User enters another index.

      Use case resumes at step 3.

  • 3b. There is no XML data currently.

    • 3b1. Error message shown.

      Use case ends.

Use Case: Edit a student’s profile picture

MSS

  1. User requests to list students.

  2. Student list panel shows a list of students.

  3. User requests to edit a student’s profile picture.

  4. Command box shows updated picture.

    Use case ends.

Extensions

  • 2a. The list is empty.

    Use case ends

  • 3a. The given index is invalid.

    • 3a1. Error message shown.

    • 3a2. User enters another index.

      Use case resumes at step 3.

  • 3b. The file path of the picture does not exist.

    • 3b1. Error message shown.

    • 3b2. User can enter another file path to the desired picture file.

      Use case resumes at step 3.

  • 3c The file path does not end with an extension of '.png' or '.jpg'.

    • 3c1. Error message shown.

    • 3c2. User can enter another file path to the desired picture file.

      Use case resumes at step 3.

  • 4a User is at the profile page while entering editPicture command.

    • 4a1. Profile picture on the profile page changes

      Use case ends.

Use Case: Edit a student’s miscellaneous information

MSS

  1. User requests to list students.

  2. Student list panel shows a list of students.

  3. User requests to edit a student’s miscellaneous information.

  4. Command box shows command success.

    Use case ends.

Extensions

  • 2a. The list is empty.

    Use case ends

  • 3a. The given index is invalid.

    • 3a1. Error message shown.

    • 3a2. User enters another index.

      Use case resumes at step 3.

  • 3b. No fields are entered.

    • 3b1. Error message shown.

    • 3b2. User enters command with specific fields which are desired to edit.

      Use case resumes at step 3.

  • 3c The prefixes are wrong.

    • 3c1. Error message shown.

    • 3c2. User enters command with proper prefixes to changes desired

      Use case resumes at step 3.

  • 4a User is at the profile page while entering editMisc command.

    • 4a1. The miscellaneous information portion is updated.

      Use case ends.

Use case: Deleting a lesson

MSS

  1. Schedule panel shows lessons and timeslots.

  2. User requests to delete a lesson identified by index.

  3. Codeducator deletes that lesson from that slot.

    Use case ends.

Extensions

  • 2a. The schedule is empty.

    Use case ends.

  • 2b. The given lesson index is invalid.

    • 2b1. Codeducator shows an error message.

      Use case resumes at step 2.

Use case: Logging in

MSS

  1. User requests to log in to Google Accounts.

  2. A window opens in user’s default browser.

  3. User logs in to Google Accounts.

  4. User authorizes Codeducator.

  5. Codeducator shows login success message

    Use case ends.

Extensions

  • 3a. User enters wrong password too many times.

    • 3a1. Codeducator goes into timeout after 45 seconds.

      Use case ends.

  • 3b. User closes his browser window.

    • 3b1. Codeducator goes into timeout after 45 seconds.

  • 4a. User does not authorise Codeducator.

    • 4a1. Codeducator shows authentication denied error.

      Use case ends.

Use case: Logging out

MSS

  1. User requests to log out of Google accounts in Codeducator

  2. Codeducator shows logout success message

    Use case ends.

Extensions

  • 1a. User was not logged in

    • 1a1. Codeducator goes into timeout after 45 seconds.

      Use case ends.

  • 3a. User closes his browser window

    • 3a1. Codeducator goes into timeout after 45 seconds.

  • 4a. User does not authorise Codeducator

    • 4a1. Codeducator shows authentication denied error

      Use case ends.

Use case: Syncing data

MSS

  1. User requests to sync data with Google services.

  2. Codeducator uploads data through network connection.

  3. Codeducator shows data sync success

    Use case ends.

Extensions

  • 2a. User’s internet get cut

    • 2a1. Codeducator goes into timeout after losing connection.

      Use case ends.

Use case: Show a student’s dashboard

MSS

  1. User requests view the dashboard of a student.

  2. Codeducator shows the dashboard the student.

    Use case ends.

Extensions

  • 1a. The student index is invalid

    • 1a1. Codeducator shows an error message.

Use case: Add a milestone to a dashboard

MSS

  1. User requests view the dashboard of a student.

  2. Codeducator shows the dashboard the student.

  3. User requests to add a specific milestone to the dashboard of that student.

  4. Codeducator adds the milestone to the dashboard of that student.

    Use case ends.

Extensions

  • 3a. The milestone is a duplicate of an existing milestone in the dashboard.

    • 3a1. Codeducator shows an error message.

Use case: Add a task to a milestone in a dashboard

MSS

  1. User requests view the dashboard of a student.

  2. Codeducator shows the dashboard the student.

  3. User requests to add a specific task to a milestone in the dashboard of that student.

  4. Codeducator adds the task to the milestone in the dashboard of that student.

    Use case ends.

Extensions

  • 3a. The task is a duplicate of an existing task in the milestone.

    • 3a1. Codeducator shows an error message.

      Use case resumes at step 2.

Use case: Delete a milestone in a dashboard

MSS

  1. User requests view the dashboard of a student.

  2. Codeducator shows the dashboard the student.

  3. User requests to delete a milestone in the dashboard of that student.

  4. Codeducator deletes the milestone in the dashboard of that student.

    Use case ends.

Extensions

  • 3a. The given student index is invalid

    • 3a1. Codeducator shows an error message.

  • 3b. The given milestone index is invalid

    • 3b1. Codeducator shows an error message.

      Use case resumes at step 2.

Use case: Delete a task in a milestone in the dashboard

MSS

  1. User requests view the dashboard of a student.

  2. Codeducator shows the dashboard the student.

  3. User requests to delete a task in a milestone in the dashboard of that student.

  4. Codeducator deletes the task in the milestone in the dashboard of that student.

    Use case ends.

Extensions

  • 3a. The given student index is invalid

    • 3a1. Codeducator shows an error message.

  • 3b. The given milestone index is invalid

    • 3b1. Codeducator shows an error message.

      Use case resumes at step 2.

  • 3c. The given task index is invalid

    • 3c1. Codeducator shows an error message.

      Use case resumes at step 2.

Use case: Mark a task in a milestone as completed

MSS

  1. User requests view the dashboard of a student.

  2. Codeducator shows the dashboard the student.

  3. User requests to mark a task in a milestone in the dashboard of that student as completed.

  4. Codeducator marks the task in the milestone in the dashboard of that student as completed.

    Use case ends.

Extensions

  • 3a. The given student index is invalid

    • 3a1. Codeducator shows an error message.

  • 3b. The given milestone index is invalid

    • 3b1. Codeducator shows an error message.

      Use case resumes at step 2.

  • 3c. The given task index is invalid

    • 3c1. Codeducator shows an error message.

      Use case resumes at step 2.

Appendix C: Non Functional Requirements

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

  2. Should be able to hold up to 1000 students 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.

  4. Should receive feedback after executing commands.

  5. Should have correct error handling and not crash from unexpected behavior.

  6. Should have its functions and commands easily understood and readable for first time users.

  7. Should be able to sync with any Google account ending with @gmail.com

Appendix D: Glossary

Mainstream OS

Windows, Linux, Unix, OS-X

Timetable

A weekly timetable that shows status of all timeslots in one hour divisions

Appendix E: Instructions for Manual Testing

Given below are instructions to test the app manually.

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

E.1. Launch and Shutdown

  1. Initial launch

    1. Download the jar file and copy into an empty folder

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

  2. Saving window preferences

    1. Resize the window to an optimum size. Move the window to a different location. Close the window.

    2. Re-launch the app by double-clicking the jar file.
      Expected: The most recent window size and location is retained.

E.2. Deleting a student

  1. Deleting a student while all students are listed

    1. Prerequisites: List all students using the list command. Multiple students in the list.

    2. Test case: delete 1
      Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated.

    3. Test case: delete 0
      Expected: No student is deleted. Error details shown in the status message. Status bar remains the same.

    4. Other incorrect delete commands to try: delete, delete x (where x is larger than the list size) {give more}
      Expected: Similar to previous.

E.3. Saving data

  1. Dealing with missing/corrupted data files

    1. Delete the contents of /data.
      Expected: Codeducator will start off with sample contacts and empty schedule, empty dashboards, empty moreinfo pages

E.4. Adding a student to favourites

  1. Adding a student to favourites while all students are listed

    1. Prerequisites: List all students using the list command and there are multiple students in the list. The first student contact is not in favourites.

    2. Test case: fav 1
      Expected:

      • The name of the first student contact in the student list will turn orange in color.

      • The name of the first student contact will be shown in the result box.

      • Timestamp in the status bar is updated.

      • Executing the command list -f will show the student in the favourites list.

    3. Test case: fav 0
      Expected:

      • No student is added to favourites due to the invalid student index.

      • Error details will be shown in the result box.

      • Timestamp in the status bar remains the same.

    4. Other incorrect favourite commands to try: fav, fav x (where x is larger than the list size)
      Expected:

      • Similar to the previous test case

E.5. Removing a student from favourites

  1. Removing a student from favourites while all students are listed

    1. Prerequisites: List all students using the list command and there are multiple students in the list. The first student contact is in favourites.

    2. Test case: unfav 1
      Expected:

      • The name of the first student contact in the student list will no longer be orange in color.

      • The name of the first student contact will be shown in the result box.

      • Timestamp in the status bar is updated.

      • Executing the command list -f will no longer show the student in the favourites list.

    3. Test case: unfav 0
      Expected:

      • No student is removed from favourites due to the invalid student index.

      • Error details will be shown in the result box.

      • Timestamp in the status bar remains the same.

    4. Other incorrect unfavourite commands to try: unfav, unfav x (where x is larger than the list size)
      Expected:

      • Similar to the previous test case

  2. Removing a student from favourites while only students in favourites are listed

    1. Prerequisites: List only students in favourites using the list -f command and there are multiple students in the list.

    2. Test case: unfav 1
      Expected:

      • First student contact in the favourites list will be removed.

      • The name of the first student contact will be shown in the result box.

      • Timestamp in the status bar is updated.

E.6. Showing the dashboard of a student

  1. Showing the dashboard of a student while all students are listed and the right panel is showing the schedule

    1. Prerequisites: List all students using the list command and there are multiple students in the list. The schedule is being displayed on the right panel using the schedule command.

    2. Test case: showDB 1
      Expected:

      • The dashboard of the first student contact in the student list replaces the schedule in the right panel.

      • The index 1 is shown in the result box.

    3. Test case: showDB 0
      Expected:

      • The schedule remains in the right panel due to the invalid student index.

      • Error details will be shown in the result box.

    4. Other incorrect show dashboard commands to try: showDB, showDB x (where x is larger than the list size)
      Expected:

      • Similar to the previous test case.

  2. Showing the dashboard of a student while all students are listed and the right panel is showing the browser panel

    1. Prerequisites: List all students using the list command and there are multiple students in the list. The 1st student in the list is being selected and the browser is being displayed on the right panel using the select command.

    2. Test case: showDB 1
      Expected:

      • The dashboard of the first student contact in the student list replaces the browser in the right panel.

      • The index 1 is shown in the result box.

E.7. Adding a milestone to a student’s dashboard

  1. Adding a milestone to a student’s dashboard while the dashboard is being shown

    1. Prerequisites: The dashboard of the 1st student in the list is being shown with the showDB 1 command.

    2. Test case: addMS i/1 d/23/05/2018 23:59 o/Learn Arrays
      Expected:

      • A milestone with the due date "23/05/2018 23:59" and description "Learn Arrays" is added to the dashboard.

      • The milestone details is shown in the result box.

      • Timestamp in the status bar is updated.

    3. Test case: addMS i/0 d/23/05/2018 23:59 o/Learn Arrays

      • Milestone is not added to the dashboard due to the invalid student index.

      • Error details will be shown in the result box.

      • Timestamp in the status bar remains the same.

    4. Test case: addMS i/1 d/31/02/2018 23:59 o/Learn Arrays

      • Milestone is not added to the dashboard due to the invalid date.

      • Error details will be shown in the result box.

      • Timestamp in the status bar remains the same.

    5. Other incorrect add milestone commands to try: addMS, addMS i/1, addMS d/23/05/2018, addMS o/Learn Arrays, addMS i/1 d/23/05/2018 23:59, addMS i/1 d/23/05/2018 o/Learn Arrays
      Expected:

      • Similar to the previous test case.

E.8. Deleting a milestone from a student’s dashboard

  1. Deleting a milestone from a student’s dashboard while the dashboard is being shown

    1. Prerequisites: The dashboard of the 1st student in the list is being shown with the showDB 1 command. The dashboard contains at least 1 milestone.

    2. Test case: deleteMS i/1 m/1
      Expected:

      • The 1st milestone in the dashboard is being deleted.

      • The milestone details is shown in the result box.

      • Timestamp in the status bar is updated.

    3. Test case: deleteMS i/1 m/x (where x is larger than the size of the milestone list)
      Expected:

      • No milestone is deleted due to the invalid milestone index.

      • Error details will be shown in the result box.

      • Timestamp in the status bar remains the same.

    4. Other incorrect delete milestone commands to try: deleteMS, deleteMS i/1, deleteMS m/1, deleteMS i/0 m/1 Expected:

      • Similar to the previous test case.

E.9. Adding a task to a milestone

  1. Adding a task to a milestone in a student’s dashboard while the dashboard is being shown

    1. Prerequisites: The dashboard of the 1st student in the list is being shown with the showDB 1 command. The dashboard contains at least 1 milestone.

    2. Test case: addTask i/1 m/1 n/Learn Array Syntax o/Student to refer to the textbook
      Expected:

      • A task with the name "Learn Array Syntax" and description "Student to refer to the textbook" is added to the 1st milestone in the dashboard.

      • The task details are shown in the result box.

      • Timestamp in the status bar is updated.

    3. Test case: addTask i/1 m/x n/Learn Array Syntax o/Student to refer to the textbook (where x larger than the size of the milestone list)
      Expected:

      • Task is not added to the milestone due to the invalid milestone index.

      • Error details will be shown in the result box.

      • Timestamp in the status bar remains the same.

    4. Other incorrect add task commands to try: addTask, addTask i/1 m/1, addTask i/1 m/1 n/Learn Array Syntax, addTask n/Learn Array Syntax o/Student to refer to the textbook
      Expected:

      • Similar to the previous test case.

E.10. Deleting a task from a milestone

  1. Deleting a task from a milestone in a student’s dashboard while the dashboard is being shown

    1. Prerequisites: The dashboard of the 1st student in the list is being shown with the showDB 1 command. The dashboard contains at least 1 milestone with at least 1 task.

    2. Test case: deleteTask i/1 m/1 tk/1
      Expected:

      • The 1st task in the 1st milestone is being deleted.

      • The task details are shown in the result box.

      • Timestamp in the status bar is updated.

    3. Test case: deleteTask i/1 m/1 tk/x (where x is larger than the size of the task list)
      Expected:

      • No task is deleted due to the invalid task index.

      • Error details will be shown in the result box.

      • Timestamp in the status bar remains the same.

    4. Other incorrect delete task commands to try: deleteTask, deleteTask tk/1, deleteTask m/1 tk/1, deleteTask i/0 m/1 tk/1, deleteTask i/1 m/0 tk/1
      Expected:

      • Similar to the previous test case.

E.11. Marking a task as completed

  1. Marking an incomplete task from a milestone in a student’s dashboard as completed while the dashboard is being shown

    1. Prerequisites: The dashboard of the 1st student in the list is being shown with the showDB 1 command. The dashboard contains at least 1 milestone with the 1st task not marked as completed.

    2. Test case: checkTask i/1 m/1 tk/1
      Expected:

      • The 1st task in the 1st milestone is marked as completed with the "Completed" field turning from "No" to "Yes".

      • The progress of the 1st milestone is updated.

      • The task index and milestone index are shown in the result box.

      • Timestamp in the status bar is updated.

    3. Test case: checkTask i/1 m/1 tk/x (where x is larger than the size of the task list)
      Expected:

      • No task is marked as completed due to the invalid task index.

      • Error details will be shown in the result box.

      • Timestamp in the status bar remains the same.

    4. Other incorrect marking task as completed command to try: checkTask, checkTask tk/1, checkTask m/1 tk/1, checkTask i/0 m/1 tk/1, checkTask i/1 m/0 tk/1
      Expected:

      • Similar to the previous test case.

  2. Marking a completed task from a milestone in a student’s dashboard as completed while the dashboard is being shown

    1. Prerequisites: The dashboard of the 1st student in the list is being shown with the showDB 1 command. The dashboard contains at least 1 milestone with the 1st task already marked as completed.

    2. Test case: checkTask i/1 m/1 tk/1
      Expected:

      • The 1st task in the 1st milestone remains marked as completed with the "Completed" field being "Yes".

      • The progress in the 1st milestone remains the same.

      • A message saying that the task is already marked as completed will be shown in the result box.

      • Timestamp in the status bar remains the same.

E.12. Displaying the profile page of a student

  1. Showing the profile page of a student with the student list on the left and the browser panel is showing currently.

    1. Prerequisites: There is at least 1 student in the contacts data and the last shown filtered list. There exists XML data of that particular student.

    2. Test case: moreInfo 1
      Expected:

      • The profile page of a student is shown.

      • The student’s main information is shown, including Name, Phone, Address , Email, ProgrammingLanguage and tags.

      • The student’s miscellaneous information is shown, including Allergies, Next Of Kin Name, Next Of Kin Phone and Remarks.

      • The student’s profile picture is displayed. Note: if he/she does not have a custom profile picture, they are assigned a placeholder picture in its place.

    3. Test case: moreInfo 0
      Expected:

      • There is no student whose index is 0. Thus the main panel on the right remains unchanged.

      • An error message is shown in the command box.

    4. Test case: moreInfo 1 with no XML data of Students
      Expected:

      • No profile page will be shown as this command only works when there is existing XML data( as mentioned in the prerequisites)

      • An error message is shown in the command box.

  2. Showing the profile page of a student with the student list on the left and the dashboard panel is showing currently

    1. Test case: moreInfo 1
      Expected:

      • The dashboard panel is switched with the browser panel.

      • The profile page of a student is loaded.

      • The student’s main information is shown, including Name, Phone, Address , Email, ProgrammingLanguage and tags.

      • The student’s miscellaneous information is shown, including Allergies, Next Of Kin Name, Next Of Kin Phone and Remarks.

      • The student’s profile picture is displayed. Note: if he/she does not have a custom profile picture, they are assigned a placeholder picture in its place.

    2. Test case: moreInfo 0
      Expected:

      • There is no student whose index is 0. Thus, the dashboard panel will still be on display and will not switch with the browser panel.

      • An error message is shown in the command box.

    3. Test case: moreInfo 1 with no XML data of Students
      Expected:

      • No profile page will be shown as this command only works when there is existing XML data( as mentioned in the prerequisites)

      • The dashboard panel will still be on display and will not switch with the browser panel.

      • An error message is shown in the command box.

E.13. Editing the miscellaneous information of a student

  1. Editing the miscellaneous information of a student while the student’s profile page is being shown on the main browser panel.

    1. Test case: editMisc 1 al/Nuts
      Expected

      • The student’s allergies portion of his/her miscellaneous information is overwritten with the string "Nuts".

      • The profile page refreshes and displays the latest updated information of the student.

      • Timestamp in the status bar is updated.

    2. Test case: editMisc 1 al/Nuts r/Naughty Expected

      • The student’s allergies portion, as well as the remarks portion, of his/her miscellaneous information is overwritten with "Nuts" and "Naughty" respectively.

      • The profile page refreshes and displays the latest updated information of the student.

      • Timestamp in the status bar is updated.

    3. Test case: editMisc 0 al/Nuts
      Expected

      • There is no student whose index is 0. Thus, the miscellaneous information of the student is not changed.

      • Information of the student on the browser panel is not changed.

      • An error message is shown in the command box.

      • Timestamp in the status bar remains the same.

    4. Test case: `editMisc 1 al/ ` Expected

      • Fields entered cannot take in empty values. Thus, the miscellaneous information of the student is not changed.

      • Information of the student on the browser panel is not changed.

      • An error message is shown in the command box.

      • Timestamp in the status bar remains the same.

E.14. Editing the profile picture of a student

  1. Editing the profile picture of a student while his/her profile page is on display on the browser panel.

    1. Test case: editPicture i/1 pa/test.jpg given "test.jpg" is a valid picture file that exists Expected

      • The student’s profile picture is overwritten with the new profile picture.

      • The picture from the filepath indicated by the user is copied onto the local data folder.

      • The profile page refreshes and displays the latest updated information of the student.

      • Timestamp in the status bar is updated.

    2. Test case: editPicture i/1 pa/C:/Users/User/Desktop/test.jpg given the file path is a valid picture file that exists Expected

      • The student’s profile picture is overwritten with the new profile picture.

      • The picture from the filepath indicated by the user is copied onto the local data folder.

      • The profile page refreshes and displays the latest updated information of the student.

      • Timestamp in the status bar is updated.

    3. Test case: editPicture i/1 pa/missingFile.jpg given the file path is a picture file that does not exists Expected

      • As the file does not exist, the profile picture of the student will not be modified.

      • The profile picture of the student displayed on the browser panel is not changed.

      • An error message is shown in the command box.

      • Timestamp in the status bar remains the same.

    4. Test case: editPicture i/1 pa/wrongFile.exe given the file path is a not a picture file but it does exist. Expected

      • As the file does not end with an extension of .jpg or png, the profile picture of the student will not be modified.

      • The profile picture of the student displayed on the browser panel is not changed.

      • An error message is shown in the command box.

      • Timestamp in the status bar remains the same.

E.15. Adding a lesson

  1. Adding a lesson while all students are listed.

    1. Prerequisites: View schedule using schedule command. List all students using the list command. Multiple students in the list. Your current schedule would preferably have no lessons starting before 7am or ending after 10pm.

    2. Test case: addLesson 1 d/mon st/10:00 et/12:00
      Expected:

      • A lesson will be added for student at index 1, starting at 10:00am, ending at 12:00pm.

    3. Test case: addLesson 1 d/wed st/00:00 et/23:59
      Expected:

      • A lesson will be added for student at index 1, on Wednesday, starting at 00:00pm, ending at 23:59pm (whole day).

      • The schedule should resize (change start and end times) to show the lesson in the whole day.

    4. Test case: addLesson 0 d/mon st/10:00 et/12:00
      Expected:

      • No lesson added.

      • Error message showing invalid student index.

  2. Adding a lesson with invalid time.

    1. Test case: addLesson 1 d/thu st/10:90 et/15:00 or addLesson 1 d/thu st/24:00 et/26:00 Expected:

      • No lesson added.

      • Error message shows invalid time format.

  3. Adding a lesson with invalid day

    1. Test case: addLesson 1 d/monday st/10:00 et/15:00 or addLesson 1 d/mo st/10:00 et/15:00 Expected:

      • No lesson added.

      • Error message shows invalid day format.

  4. Adding a lesson for a filtered list after using find or findTag command.

    1. Prerequisites: List a filtered list of students using the find or findTag command. Single or multiple students in the list. Your current schedule would preferably have no lessons starting before 7am or ending after 10pm.

    2. Same test cases as when all students are listed, but should work for a smaller index range due to a smaller list of filtered students.

E.16. Deleting a Lesson

  1. Deleting a lesson from schedule

    1. Prerequisites: Add a few lessons into the schedule. Take note of display lesson indexes of your lessons.

    2. Test case: deleteLesson 1
      Expected:

      • The lesson with displayed lesson index 1 will be deleted.

      • Schedule will resize to between 07:00 and 22:00 if no lesson on any day ends later than that.

      • Message shows lesson deleted.

    3. Test case: deleteLesson 0
      Expected:

      • No lesson will be added due to invalid student index. Error details shown in results screen.

    4. Other incorrect deleteLessons commands to try: deleteLesson, deleteLesson x where x is larger than the index of the last lesson.

E.17. Logging in to Google Accounts

The testing will only include interactions with Codeducator. Login procedure to Google Accounts is handled by Google

  1. Prerequisites: Valid Google account, you know your username and password, ending in @gmail.com

  2. Test case: Successfully logging in after executing login command.
    Expected:

    • Message shows login success

    • Now able to sync data.

    • Now able to logout.

    • Trying to login again results in error message that you are already logged in.

  3. Test case: Unable to login successfully to Google Accounts within 45 seconds.
    Expected

    • Error message shows timeout.

    • Unable to sync data.

    • Unable to logout.

    • Able to login again.

  4. Test case: Ignoring the login screen for 45 seconds.
    Expected

    • Same as unable to login successfully

  5. Test case: Wrong Google account username and password.
    Expected

    • Same as unable to login successfully

E.18. Logging out of Google Accounts.

  1. Prerequisites: Valid Google account, you know your username and password, ending in @gmail.com. Already logged in

  2. Test case: Successfully logging in after executing logout command

    • Message shows logout success

    • Unable to sync data.

    • Unable to logout.

    • Able to login again.

  3. Test case: Execute logout without logging in first.
    Expected

    • Error message shows not logged in

E.19. Syncing data

  1. Prerequisites:

    • Valid Google account, you know your username and password, ending in @gmail.com.
      Expected:

    • Already logged in

    • Some contact data and schedule data

  2. Test case: executing sync
    Expected:

    • May take some time to sync

    • In contacts.google.com, you can see your contacts data synced. Codeducator contacts are grouped under the label "Students".

    • In calendar.google.com, you can see your schedule synced. Codeducator events are grouped under the calendar "Student lessons"

    • Message shows sync success.

    • Message

  3. Test case: executing sync again after editing some data e.g. add, edit, delete, addLesson, deleteLesson
    Expected:

    • May take some time to sync

    • In contacts.google.com, you can see your contacts data synced. Updated Codeducator contacts are grouped under the label "Students".

    • In calendar.google.com, you can see your schedule synced. Updated Codeducator events are grouped under the calendar "Student lessons"

    • Message shows sync success.

  4. Test case: Executing sync without logging in.
    Expected:

    • Error message shows not logged in