From f2836b72e15a7cfac3e271a533acc5362a801503 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Mon, 5 Nov 2018 00:11:17 +0800 Subject: [PATCH 01/32] Added author tag --- src/main/java/seedu/address/logic/parser/ParserUtil.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index fc2608550342..96723b1410e8 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -185,6 +185,7 @@ public static Tag parseTag(String tag) throws ParseException { return new Tag(trimmedTag); } + //@@author EatOrBeEaten /** * Parses {@code Collection tags} into a {@code Set}. */ From 347241bc6cb69ed910f17e5f4bb76b70029d2809 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Mon, 5 Nov 2018 00:11:35 +0800 Subject: [PATCH 02/32] Fixed error message for content constraints --- src/main/java/seedu/address/model/email/Content.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/model/email/Content.java b/src/main/java/seedu/address/model/email/Content.java index ffe31a3b9596..dba79be83677 100644 --- a/src/main/java/seedu/address/model/email/Content.java +++ b/src/main/java/seedu/address/model/email/Content.java @@ -12,7 +12,7 @@ public class Content { public static final String MESSAGE_CONTENT_CONSTRAINTS = - "Subject can take any values, and it should not be blank"; + "Content can take any values, and it should not be blank"; /* * The first character of the content must not be a whitespace, From 56bc46bc8af00333b45226cd15ccdb244ec62e84 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Mon, 5 Nov 2018 00:11:56 +0800 Subject: [PATCH 03/32] Edited User Guide for compose email index --- docs/UserGuide.adoc | 32 +++++++++++++++---- .../commands/ComposeEmailIndexCommand.java | 2 +- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 54e1a5a7e0cc..18a44da23465 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -297,15 +297,27 @@ Format: `compose_email_index from/FROM to/INDEXES subject/SUBJECT content/CONTEN * INDEXES *must be positive integers* 1, 2, 3, ... * SUBJECT has no word limit. * CONTENT has no word limit. +* `
` can be used in CONTENT for new line. **** +[TIP] +==== +CONTENT is written in HTML. Users who know HTML can use it to format the CONTENT. +==== + Example: -* `compose_email_index from/johndoe@example.com to/1 6 10 subject/Meeting this Friday -content/Hey there's a meeting this friday.` + -Composes an email from `johndoe@example.com` to people at indexes 1, 6 and 10 with subject -`Meeting this Friday` and email body `Hey there's a meeting this friday.` and saves -it as a *`.eml`* file. +* `list` + +`compose_email_index from/johndoe@example.com to/1 3 5 subject/Meeting this Friday +content/Dear All

There's a meeting this friday.

John Doe` + +Composes an email from `johndoe@example.com` to residents at indexes 1, 3, and 5 with subject +`Meeting this Friday` and email body + +`Dear All` + ++ +`There's a meeting this friday.` + ++ +`John Doe` + +and saves it as a *`.eml`* file. ==== Composing an email to currently listed people: `compose_email_list` Composes a *`.eml`* file that can be used to send emails to currently listed residents. + @@ -317,9 +329,15 @@ Format: `compose_email_list from/FROM subject/SUBJECT content/CONTENT` * CONTENT has no word limit. **** +[TIP] +==== +CONTENT is written in HTML. Users who know HTML can use it to format the CONTENT. +==== + Example: -* `compose_email_list from/johndoe@example.com subject/Meeting this Friday +* `list` + +`compose_email_list from/johndoe@example.com subject/Meeting this Friday content/Hey there's a meeting this friday.` + Composes an email from `johndoe@example.com` to currently listed people with subject `Meeting this Friday` and email body `Hey there's a meeting this friday.` and saves @@ -716,7 +734,7 @@ e.g. `search basketball A123` ===== Email * *Compose Email (Index)* : `compose_email_index from/FROM to/INDEXES subject/SUBJECT content/CONTENT` + -e.g. `compose_email_index from/johndoe@example.com to/1 6 10 subject/Meeting this Friday content/Hey there's a meeting this friday.` +e.g. `compose_email_index from/johndoe@example.com to/1 3 5 subject/Meeting this Friday content/Hey there's a meeting this friday.` * *Compose Email (List)* : `compose_email_list from/FROM subject/SUBJECT content/CONTENT` + e.g. `compose_email_list from/johndoe@example.com subject/Meeting this Friday content/Hey there's a meeting this friday.` * *List Emails* : `list_emails` diff --git a/src/main/java/seedu/address/logic/commands/ComposeEmailIndexCommand.java b/src/main/java/seedu/address/logic/commands/ComposeEmailIndexCommand.java index 69f5a0194aaf..bc9d0b341ff6 100644 --- a/src/main/java/seedu/address/logic/commands/ComposeEmailIndexCommand.java +++ b/src/main/java/seedu/address/logic/commands/ComposeEmailIndexCommand.java @@ -37,7 +37,7 @@ public class ComposeEmailIndexCommand extends Command { + PREFIX_CONTENT + "CONTENT(Input
for newline)\n" + "Example: " + COMMAND_WORD + " " + PREFIX_FROM + "johndoe@example.com " - + PREFIX_TO + "1 6 10 " + + PREFIX_TO + "1 3 5 " + PREFIX_SUBJECT + "Meeting this Friday " + PREFIX_CONTENT + "Dear All

Remember our meeting this friday.

John"; From 09328405d0896a65e3f7b70881e1dc4447010b60 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Mon, 5 Nov 2018 01:33:10 +0800 Subject: [PATCH 04/32] Changed example added images in User Guide for Email feature --- docs/UserGuide.adoc | 33 ++++++++++++++++++---------- docs/images/compose_email_index.png | Bin 0 -> 44783 bytes docs/images/compose_email_list.png | Bin 0 -> 37860 bytes docs/images/list.png | Bin 0 -> 22957 bytes docs/images/view_email.png | Bin 0 -> 38146 bytes 5 files changed, 21 insertions(+), 12 deletions(-) create mode 100644 docs/images/compose_email_index.png create mode 100644 docs/images/compose_email_list.png create mode 100644 docs/images/list.png create mode 100644 docs/images/view_email.png diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 18a44da23465..58dfa9901c7b 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -284,6 +284,8 @@ Returns any person having names `Betsy`, `Tim`, or `John` Shows a list of all persons in Hallper. + Format: `list` +image::list.png[width="790"] + === Email This section lists features related to email in Hallper. @@ -292,7 +294,7 @@ Composes a *`.eml`* file that can be used to send emails to residents specified Format: `compose_email_index from/FROM to/INDEXES subject/SUBJECT content/CONTENT` **** -* FROM must be a valid email address e.g. johndoe@example.com +* FROM must be a valid email address. E.g. johndoe@example.com * INDEXES refer to the index numbers shown in the displayed person list. * INDEXES *must be positive integers* 1, 2, 3, ... * SUBJECT has no word limit. @@ -307,24 +309,23 @@ CONTENT is written in HTML. Users who know HTML can use it to format the CONTENT Example: -* `list` + +* `list` ++ +image::list.PNG[width="790"] ++ `compose_email_index from/johndoe@example.com to/1 3 5 subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` + Composes an email from `johndoe@example.com` to residents at indexes 1, 3, and 5 with subject -`Meeting this Friday` and email body + -`Dear All` + -+ -`There's a meeting this friday.` + +`Meeting this Friday` and email body `Dear All

There's a meeting this friday.

John Doe` and saves it as a *`.eml`* file. + -`John Doe` + -and saves it as a *`.eml`* file. +image::compose_email_index.png[width="790"] ==== Composing an email to currently listed people: `compose_email_list` Composes a *`.eml`* file that can be used to send emails to currently listed residents. + Format: `compose_email_list from/FROM subject/SUBJECT content/CONTENT` **** -* FROM must be a valid email address e.g. johndoe@example.com +* FROM must be a valid email address. E.g. johndoe@example.com * SUBJECT has no word limit. * CONTENT has no word limit. **** @@ -336,12 +337,17 @@ CONTENT is written in HTML. Users who know HTML can use it to format the CONTENT Example: -* `list` + +* `list` ++ +image::list.PNG[width="790"] ++ `compose_email_list from/johndoe@example.com subject/Meeting this Friday -content/Hey there's a meeting this friday.` + +content/Dear All

There's a meeting this friday.

John Doe` + Composes an email from `johndoe@example.com` to currently listed people with subject -`Meeting this Friday` and email body `Hey there's a meeting this friday.` and saves +`Meeting this Friday` and email body `Dear All

There's a meeting this friday.

John Doe` and saves it as a *`.eml`* file. ++ +image::compose_email_list.PNG[width="790"] ==== Deleting an email : `delete_email` @@ -375,6 +381,9 @@ Examples: * `view_email Meeting on Friday` + Displays the email with the subject `Meeting on Friday`. ++ +.Result after executing `view_email Meeting on Friday` +image::view_email.png[width="790"] === Calendar This section lists features related to managing the calendar in Hallper. diff --git a/docs/images/compose_email_index.png b/docs/images/compose_email_index.png new file mode 100644 index 0000000000000000000000000000000000000000..6c4365193c077ebee853f7343b987133fa9c812c GIT binary patch literal 44783 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 YOGD?jj3J$|Mtkp<)p8x;= literal 0 HcmV?d00001 diff --git a/docs/images/list.png b/docs/images/list.png new file mode 100644 index 0000000000000000000000000000000000000000..1d841e00291762c4849d5a5b82b442050f9ebdaf GIT binary patch literal 22957 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 literal 0 HcmV?d00001 diff --git a/docs/images/view_email.png b/docs/images/view_email.png new file mode 100644 index 0000000000000000000000000000000000000000..e2b5db4c0a5f9538037f3d0165e44367728466f8 GIT binary patch literal 38146 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 jDH_quc-fB((~MSypURAdRurX)3b1+8_HT Date: Mon, 5 Nov 2018 01:35:32 +0800 Subject: [PATCH 05/32] Fixed image filenames in User Guide --- docs/UserGuide.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 58dfa9901c7b..a39a7baafa07 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -311,7 +311,7 @@ Example: * `list` + -image::list.PNG[width="790"] +image::list.png[width="790"] + `compose_email_index from/johndoe@example.com to/1 3 5 subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` + @@ -339,7 +339,7 @@ Example: * `list` + -image::list.PNG[width="790"] +image::list.png[width="790"] + `compose_email_list from/johndoe@example.com subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` + @@ -347,7 +347,7 @@ Composes an email from `johndoe@example.com` to currently listed people with sub `Meeting this Friday` and email body `Dear All

There's a meeting this friday.

John Doe` and saves it as a *`.eml`* file. + -image::compose_email_list.PNG[width="790"] +image::compose_email_list.png[width="790"] ==== Deleting an email : `delete_email` From 97fe4fb7bae1b7661825852b17f50ca703d7e563 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Mon, 5 Nov 2018 01:56:51 +0800 Subject: [PATCH 06/32] Added figure captions for Email --- docs/UserGuide.adoc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index a39a7baafa07..7edb6620d3a3 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -311,6 +311,7 @@ Example: * `list` + +.Result after executing `list` image::list.png[width="790"] + `compose_email_index from/johndoe@example.com to/1 3 5 subject/Meeting this Friday @@ -318,6 +319,7 @@ content/Dear All

There's a meeting this friday.

John Doe` + Composes an email from `johndoe@example.com` to residents at indexes 1, 3, and 5 with subject `Meeting this Friday` and email body `Dear All

There's a meeting this friday.

John Doe` and saves it as a *`.eml`* file. + +.Result after executing `compose_email_index from/johndoe@example.com to/1 3 5 subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` image::compose_email_index.png[width="790"] ==== Composing an email to currently listed people: `compose_email_list` @@ -339,14 +341,15 @@ Example: * `list` + +.Result after executing `list` image::list.png[width="790"] + -`compose_email_list from/johndoe@example.com subject/Meeting this Friday -content/Dear All

There's a meeting this friday.

John Doe` + +`compose_email_list from/johndoe@example.com subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` + Composes an email from `johndoe@example.com` to currently listed people with subject `Meeting this Friday` and email body `Dear All

There's a meeting this friday.

John Doe` and saves it as a *`.eml`* file. + +.Result after executing `compose_email_list from/johndoe@example.com subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` image::compose_email_list.png[width="790"] ==== Deleting an email : `delete_email` From 3d41ce9303836728f5c3bd4fe42e4d8d68dd7adf Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Mon, 5 Nov 2018 02:12:13 +0800 Subject: [PATCH 07/32] Added point to compose_email_list --- docs/UserGuide.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 7edb6620d3a3..291150a791c9 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -330,6 +330,7 @@ Format: `compose_email_list from/FROM subject/SUBJECT content/CONTENT` * FROM must be a valid email address. E.g. johndoe@example.com * SUBJECT has no word limit. * CONTENT has no word limit. +* `
` can be used in CONTENT for new line. **** [TIP] From 410c3b1514556eedf82d34f76f97f8be8a2692ff Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Mon, 5 Nov 2018 02:16:08 +0800 Subject: [PATCH 08/32] Added whitespace --- docs/UserGuide.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 291150a791c9..50fea56fcd20 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -314,6 +314,8 @@ Example: .Result after executing `list` image::list.png[width="790"] + +[none] ++ `compose_email_index from/johndoe@example.com to/1 3 5 subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` + Composes an email from `johndoe@example.com` to residents at indexes 1, 3, and 5 with subject @@ -345,6 +347,8 @@ Example: .Result after executing `list` image::list.png[width="790"] + +[none] ++ `compose_email_list from/johndoe@example.com subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` + Composes an email from `johndoe@example.com` to currently listed people with subject `Meeting this Friday` and email body `Dear All

There's a meeting this friday.

John Doe` and saves From 3739937c01de85c8befd56f2027f70a4cd83a272 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Mon, 5 Nov 2018 02:31:17 +0800 Subject: [PATCH 09/32] Testing whitespace --- docs/UserGuide.adoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 50fea56fcd20..3aee05c826fa 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -315,7 +315,6 @@ Example: image::list.png[width="790"] + [none] -+ `compose_email_index from/johndoe@example.com to/1 3 5 subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` + Composes an email from `johndoe@example.com` to residents at indexes 1, 3, and 5 with subject @@ -348,7 +347,6 @@ Example: image::list.png[width="790"] + [none] -+ `compose_email_list from/johndoe@example.com subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` + Composes an email from `johndoe@example.com` to currently listed people with subject `Meeting this Friday` and email body `Dear All

There's a meeting this friday.

John Doe` and saves From 405bf445138e7e4154cd2441fec271de983ebd32 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Mon, 5 Nov 2018 02:36:10 +0800 Subject: [PATCH 10/32] testing whitespace --- docs/UserGuide.adoc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 3aee05c826fa..b69c2a95ddb2 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -314,7 +314,9 @@ Example: .Result after executing `list` image::list.png[width="790"] + -[none] + + ++ `compose_email_index from/johndoe@example.com to/1 3 5 subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` + Composes an email from `johndoe@example.com` to residents at indexes 1, 3, and 5 with subject @@ -346,7 +348,9 @@ Example: .Result after executing `list` image::list.png[width="790"] + -[none] + + ++ `compose_email_list from/johndoe@example.com subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` + Composes an email from `johndoe@example.com` to currently listed people with subject `Meeting this Friday` and email body `Dear All

There's a meeting this friday.

John Doe` and saves From 9f797d7518526d4c70f120a26214c361c3127e80 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Mon, 5 Nov 2018 02:39:54 +0800 Subject: [PATCH 11/32] Inserted whitespace --- docs/UserGuide.adoc | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index b69c2a95ddb2..726a4a415287 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -313,10 +313,7 @@ Example: + .Result after executing `list` image::list.png[width="790"] -+ - - -+ +{empty} + `compose_email_index from/johndoe@example.com to/1 3 5 subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` + Composes an email from `johndoe@example.com` to residents at indexes 1, 3, and 5 with subject @@ -347,10 +344,7 @@ Example: + .Result after executing `list` image::list.png[width="790"] -+ - - -+ +{empty} + `compose_email_list from/johndoe@example.com subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` + Composes an email from `johndoe@example.com` to currently listed people with subject `Meeting this Friday` and email body `Dear All

There's a meeting this friday.

John Doe` and saves From f037ac63852f20b379c2179bb1b6a2b95ae63047 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Tue, 6 Nov 2018 02:00:40 +0800 Subject: [PATCH 12/32] Slight edits to email feature in DG and UG --- docs/DeveloperGuide.adoc | 10 +++++----- docs/UserGuide.adoc | 8 +++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 44b2b986d152..babff28dd220 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -18,8 +18,8 @@ By: `Team W16-1`      Since: `Aug 2018`      Licence: `MIT` == Introduction -Hallper is a desktop application aimed at serving <> of the Halls of NUS. -Hallper follows an event-driven architecture, and is designed to work on any <>. +Hallper is a desktop application aimed at serving the Junior Common Room Committees (<>) of the Halls of NUS. +Hallper follows an event-driven architecture, and is designed to work on any <>. This guide provides you with information on how to contribute to Hallper, whether you are a new or experienced developer. == Setting up @@ -364,7 +364,7 @@ image::UndoRedoActivityDiagram.png[width="650"] === Compose email feature ==== Current Implementation -The Compose feature works using a third-party dependency, http://www.simplejavamail.org/#/about[Simple Java Mail]. +The Compose email feature works using a third-party dependency, http://www.simplejavamail.org/#/about[Simple Java Mail]. It allows `.eml` files to be saved onto the computer. The feature is facilitated by `EmailModel` and `EmailDirStorage`. It implements the following operations: @@ -407,9 +407,9 @@ The library is easy to understand so any new developer can easily extend the cur ** Cons: Users unfamiliar with HTML minimally has to learn how the `
` tag works. * **Alternative 2:** Plain text ** Pros: Plain text is easily understood by almost any user. -** Cons: The design of the email content is limited. +** Cons: The design of the email content is very limited. -//end::compose[] +// end::compose[] // tag::calendar[] === Calendar feature diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 726a4a415287..909623200922 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -286,6 +286,7 @@ Format: `list` image::list.png[width="790"] +// tag::email[] === Email This section lists features related to email in Hallper. @@ -295,7 +296,7 @@ Format: `compose_email_index from/FROM to/INDEXES subject/SUBJECT content/CONTEN **** * FROM must be a valid email address. E.g. johndoe@example.com -* INDEXES refer to the index numbers shown in the displayed person list. +* INDEXES refer to the index numbers shown in the displayed resident list. * INDEXES *must be positive integers* 1, 2, 3, ... * SUBJECT has no word limit. * CONTENT has no word limit. @@ -322,7 +323,7 @@ Composes an email from `johndoe@example.com` to residents at indexes 1, 3, and 5 .Result after executing `compose_email_index from/johndoe@example.com to/1 3 5 subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` image::compose_email_index.png[width="790"] -==== Composing an email to currently listed people: `compose_email_list` +==== Composing an email to currently listed residents: `compose_email_list` Composes a *`.eml`* file that can be used to send emails to currently listed residents. + Format: `compose_email_list from/FROM subject/SUBJECT content/CONTENT` @@ -346,7 +347,7 @@ Example: image::list.png[width="790"] {empty} + `compose_email_list from/johndoe@example.com subject/Meeting this Friday content/Dear All

There's a meeting this friday.

John Doe` + -Composes an email from `johndoe@example.com` to currently listed people with subject +Composes an email from `johndoe@example.com` to currently listed residents with subject `Meeting this Friday` and email body `Dear All

There's a meeting this friday.

John Doe` and saves it as a *`.eml`* file. + @@ -388,6 +389,7 @@ Displays the email with the subject `Meeting on Friday`. + .Result after executing `view_email Meeting on Friday` image::view_email.png[width="790"] +// end::email[] === Calendar This section lists features related to managing the calendar in Hallper. From 9c557763622d6e49db7c7879636e710425788d68 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Tue, 6 Nov 2018 02:40:15 +0800 Subject: [PATCH 13/32] Added ViewEmailCommandParserTest --- .../commands/AddCommandIntegrationTest.java | 2 +- .../parser/ViewEmailCommandParserTest.java | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/test/java/seedu/address/logic/parser/ViewEmailCommandParserTest.java diff --git a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java index bb32b95603ee..907c8a330380 100644 --- a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java +++ b/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java @@ -35,7 +35,7 @@ public void execute_newPerson_success() { Person validPerson = new PersonBuilder().build(); Model expectedModel = new ModelManager(model.getAddressBook(), new BudgetBook(), new UserPrefs(), - new HashSet<>()); + model.getExistingEmails()); expectedModel.addPerson(validPerson); expectedModel.commitAddressBook(); diff --git a/src/test/java/seedu/address/logic/parser/ViewEmailCommandParserTest.java b/src/test/java/seedu/address/logic/parser/ViewEmailCommandParserTest.java new file mode 100644 index 000000000000..32d3d2a10ecd --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/ViewEmailCommandParserTest.java @@ -0,0 +1,31 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; + +import org.junit.Test; + +import seedu.address.logic.commands.ViewEmailCommand; +import seedu.address.model.email.Subject; + +//@@author EatOrBeEaten +public class ViewEmailCommandParserTest { + + private static final String MESSAGE_INVALID_FORMAT = + String.format(MESSAGE_INVALID_COMMAND_FORMAT, ViewEmailCommand.MESSAGE_USAGE); + + private ViewEmailCommandParser parser = new ViewEmailCommandParser(); + + @Test + public void parse_emptyArg_throwsParseException() { + + // no subject specified + assertParseFailure(parser, " ", MESSAGE_INVALID_FORMAT); + } + + @Test + public void parse_validArgs_returnsViewEmailCommand() { + assertParseSuccess(parser, "Meeting", new ViewEmailCommand(new Subject("Meeting"))); + } +} From f8e1b84be3d548ca935f072be340278b902173b8 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Tue, 6 Nov 2018 02:51:00 +0800 Subject: [PATCH 14/32] Added DeleteEmailCommandParserTest --- .../parser/DeleteEmailCommandParserTest.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/test/java/seedu/address/logic/parser/DeleteEmailCommandParserTest.java diff --git a/src/test/java/seedu/address/logic/parser/DeleteEmailCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteEmailCommandParserTest.java new file mode 100644 index 000000000000..60bade17fc0f --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/DeleteEmailCommandParserTest.java @@ -0,0 +1,31 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; + +import org.junit.Test; + +import seedu.address.logic.commands.DeleteEmailCommand; +import seedu.address.model.email.Subject; + +//@@author EatOrBeEaten +public class DeleteEmailCommandParserTest { + + private static final String MESSAGE_INVALID_FORMAT = + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteEmailCommand.MESSAGE_USAGE); + + private DeleteEmailCommandParser parser = new DeleteEmailCommandParser(); + + @Test + public void parse_emptyArg_throwsParseException() { + + // no subject specified + assertParseFailure(parser, " ", MESSAGE_INVALID_FORMAT); + } + + @Test + public void parse_validArgs_returnsDeleteEmailCommand() { + assertParseSuccess(parser, "Meeting", new DeleteEmailCommand(new Subject("Meeting"))); + } +} From 6ae0e709708b3c500e3583aecafe395413674fca Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Tue, 6 Nov 2018 02:59:00 +0800 Subject: [PATCH 15/32] Fixed checkstyle error --- .../seedu/address/logic/commands/AddCommandIntegrationTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java index 907c8a330380..cc237054f0d8 100644 --- a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java +++ b/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java @@ -4,8 +4,6 @@ import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; -import java.util.HashSet; - import org.junit.Before; import org.junit.Test; From 7d3adbf039d21e5ede0304e315e3a13efb67186e Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Tue, 6 Nov 2018 13:58:18 +0800 Subject: [PATCH 16/32] Added EmailModelTest --- .../java/seedu/address/model/EmailModel.java | 6 +++ .../seedu/address/model/EmailModelTest.java | 43 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/test/java/seedu/address/model/EmailModelTest.java diff --git a/src/main/java/seedu/address/model/EmailModel.java b/src/main/java/seedu/address/model/EmailModel.java index c634dd335329..956c2f4bcbc0 100644 --- a/src/main/java/seedu/address/model/EmailModel.java +++ b/src/main/java/seedu/address/model/EmailModel.java @@ -1,5 +1,7 @@ package seedu.address.model; +import static java.util.Objects.requireNonNull; + import java.util.HashSet; import java.util.Iterator; import java.util.Set; @@ -74,7 +76,11 @@ public String getPreview() { return preview; } + /** + * Returns true if an email with the same subject as {@code fileName} exists in the EmailModel. + */ public boolean hasEmail(String fileName) { + requireNonNull(fileName); return existingEmails.contains(fileName + emlExtension); } diff --git a/src/test/java/seedu/address/model/EmailModelTest.java b/src/test/java/seedu/address/model/EmailModelTest.java new file mode 100644 index 000000000000..1ecf56268d52 --- /dev/null +++ b/src/test/java/seedu/address/model/EmailModelTest.java @@ -0,0 +1,43 @@ +package seedu.address.model; + +import static junit.framework.TestCase.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static seedu.address.testutil.TypicalEmails.MEETING_EMAIL; + +import java.util.Collections; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +//@@author EatOrBeEaten +public class EmailModelTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private final EmailModel emailModel = new EmailModel(); + + @Test + public void constructor() { + assertEquals(Collections.emptySet(), emailModel.getExistingEmails()); + } + + @Test + public void hasEmail_nullEmail_throwsNullPointerException() { + thrown.expect(NullPointerException.class); + emailModel.hasEmail(null); + } + + @Test + public void hasEmail_emailNotInEmailModel_returnsFalse() { + assertFalse(emailModel.hasEmail(MEETING_EMAIL.getSubject())); + } + + @Test + public void hasEmail_emailInEmailModel_returnsTrue() { + emailModel.saveComposedEmail(MEETING_EMAIL); + assertTrue(emailModel.hasEmail(MEETING_EMAIL.getSubject())); + } +} From 46d454fcaaa2a85d3776aa3ac4d695a77719c8c2 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Tue, 6 Nov 2018 14:01:58 +0800 Subject: [PATCH 17/32] Edited getExistingEmails to return unmodifiableSet --- src/main/java/seedu/address/model/EmailModel.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/model/EmailModel.java b/src/main/java/seedu/address/model/EmailModel.java index 956c2f4bcbc0..741df756508a 100644 --- a/src/main/java/seedu/address/model/EmailModel.java +++ b/src/main/java/seedu/address/model/EmailModel.java @@ -2,6 +2,7 @@ import static java.util.Objects.requireNonNull; +import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; @@ -65,7 +66,7 @@ public void saveComposedEmail(Email email) { } public Set getExistingEmails() { - return existingEmails; + return Collections.unmodifiableSet(existingEmails); } public Email getEmail() { From f5fd21636abff439f161ed3cacccca216fa812e1 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Tue, 6 Nov 2018 15:18:09 +0800 Subject: [PATCH 18/32] Added test case of EmailModelTest --- src/main/java/seedu/address/model/EmailModel.java | 2 +- src/test/java/seedu/address/model/EmailModelTest.java | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/model/EmailModel.java b/src/main/java/seedu/address/model/EmailModel.java index 741df756508a..843283824e9d 100644 --- a/src/main/java/seedu/address/model/EmailModel.java +++ b/src/main/java/seedu/address/model/EmailModel.java @@ -27,7 +27,7 @@ public EmailModel() { } public EmailModel(Set emailNamesSet) { - existingEmails = new HashSet<>(); + this(); existingEmails.addAll(emailNamesSet); } diff --git a/src/test/java/seedu/address/model/EmailModelTest.java b/src/test/java/seedu/address/model/EmailModelTest.java index 1ecf56268d52..7deaed9ffb88 100644 --- a/src/test/java/seedu/address/model/EmailModelTest.java +++ b/src/test/java/seedu/address/model/EmailModelTest.java @@ -40,4 +40,10 @@ public void hasEmail_emailInEmailModel_returnsTrue() { emailModel.saveComposedEmail(MEETING_EMAIL); assertTrue(emailModel.hasEmail(MEETING_EMAIL.getSubject())); } + + @Test + public void getExistingEmails_modifySet_throwsUnsupportedOperationException() { + thrown.expect(UnsupportedOperationException.class); + emailModel.getExistingEmails().add("Hello"); + } } From 9caf45e5a31f2c08161c8772f0f0062aab44e750 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Tue, 6 Nov 2018 16:37:19 +0800 Subject: [PATCH 19/32] Added test cases to EmailModelTest --- .../java/seedu/address/model/EmailModel.java | 4 ++++ .../seedu/address/model/EmailModelTest.java | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/main/java/seedu/address/model/EmailModel.java b/src/main/java/seedu/address/model/EmailModel.java index 843283824e9d..3827f58f9546 100644 --- a/src/main/java/seedu/address/model/EmailModel.java +++ b/src/main/java/seedu/address/model/EmailModel.java @@ -28,6 +28,7 @@ public EmailModel() { public EmailModel(Set emailNamesSet) { this(); + requireNonNull(emailNamesSet); existingEmails.addAll(emailNamesSet); } @@ -36,6 +37,7 @@ public EmailModel(Set emailNamesSet) { * @param email The email to be saved. */ public void saveEmail(Email email) { + requireNonNull(email); this.email = email; savePreview(); } @@ -61,6 +63,8 @@ private void savePreview() { * @param email the newly composed email. */ public void saveComposedEmail(Email email) { + requireNonNull(email); + assert !hasEmail(email.getSubject()); saveEmail(email); addToExistingEmails(email.getSubject()); } diff --git a/src/test/java/seedu/address/model/EmailModelTest.java b/src/test/java/seedu/address/model/EmailModelTest.java index 7deaed9ffb88..dbadeffbf417 100644 --- a/src/test/java/seedu/address/model/EmailModelTest.java +++ b/src/test/java/seedu/address/model/EmailModelTest.java @@ -24,6 +24,24 @@ public void constructor() { assertEquals(Collections.emptySet(), emailModel.getExistingEmails()); } + @Test + public void constructor_nullSet_throwsNullPointerException() { + thrown.expect(NullPointerException.class); + new EmailModel(null); + } + + @Test + public void saveEmail_nullEmail_throwsNullPointerException() { + thrown.expect(NullPointerException.class); + emailModel.saveEmail(null); + } + + @Test + public void saveComposedEmail_nullEmail_throwsNullPointerException() { + thrown.expect(NullPointerException.class); + emailModel.saveComposedEmail(null); + } + @Test public void hasEmail_nullEmail_throwsNullPointerException() { thrown.expect(NullPointerException.class); From bd34744651faac8054d46ab886e338da5b2f944e Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Tue, 6 Nov 2018 17:29:59 +0800 Subject: [PATCH 20/32] Added equals method to EmailModel --- src/main/java/seedu/address/model/EmailModel.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/seedu/address/model/EmailModel.java b/src/main/java/seedu/address/model/EmailModel.java index 3827f58f9546..d9926d679125 100644 --- a/src/main/java/seedu/address/model/EmailModel.java +++ b/src/main/java/seedu/address/model/EmailModel.java @@ -97,4 +97,11 @@ public void removeFromExistingEmails(String fileName) { existingEmails.remove(fileName + emlExtension); } + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof EmailModel + && existingEmails.equals(((EmailModel) other).existingEmails)); + } + } From 6db37257cac00e46a76baffec48ffdd73f66720f Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Tue, 6 Nov 2018 17:30:27 +0800 Subject: [PATCH 21/32] Edited equals method in ModelManager and equals test in ModelManagerTest --- .../seedu/address/model/ModelManager.java | 13 +++++--- .../seedu/address/model/ModelManagerTest.java | 32 +++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index f3f2b10aefc7..92745232b4ab 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -474,18 +474,22 @@ public boolean equals(Object obj) { // state check ModelManager other = (ModelManager) obj; if (filteredPersons == null) { - return versionedAddressBook.equals(other.versionedAddressBook); + return versionedAddressBook.equals(other.versionedAddressBook) + && calendarModel.equals(other.calendarModel) + && emailModel.equals(other.emailModel); } else if (calendarModel == null) { return versionedAddressBook.equals(other.versionedAddressBook) - && filteredPersons.equals(other.filteredPersons); + && filteredPersons.equals(other.filteredPersons) + && emailModel.equals(other.emailModel); } return versionedAddressBook.equals(other.versionedAddressBook) && filteredPersons.equals(other.filteredPersons) - && calendarModel.equals(other.calendarModel); + && calendarModel.equals(other.calendarModel) + && emailModel.equals(other.emailModel); } //@@author EatOrBeEaten - //=========== Compose email ================================================================================= + //=========== Email ================================================================================= @Override public void saveEmail(Email email) { @@ -507,6 +511,7 @@ public void deleteEmail(String fileName) { @Override public boolean hasEmail(String fileName) { + requireNonNull(fileName); return emailModel.hasEmail(fileName); } diff --git a/src/test/java/seedu/address/model/ModelManagerTest.java b/src/test/java/seedu/address/model/ModelManagerTest.java index 09999d82a66d..05fe17a3b68d 100644 --- a/src/test/java/seedu/address/model/ModelManagerTest.java +++ b/src/test/java/seedu/address/model/ModelManagerTest.java @@ -3,6 +3,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; +import static seedu.address.testutil.TypicalEmails.MEETING_EMAIL; import static seedu.address.testutil.TypicalPersons.ALICE; import static seedu.address.testutil.TypicalPersons.BENSON; @@ -12,10 +13,13 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.simplejavamail.email.Email; +import junit.framework.TestCase; import seedu.address.model.person.NameContainsKeywordsPredicate; import seedu.address.model.person.Person; import seedu.address.testutil.AddressBookBuilder; +import seedu.address.testutil.DefaultEmailBuilder; public class ModelManagerTest { @Rule @@ -40,6 +44,29 @@ public void hasPerson_personInAddressBook_returnsTrue() { assertTrue(modelManager.hasPerson(ALICE)); } + @Test + public void hasEmail_nullEmail_throwsNullPointerException() { + thrown.expect(NullPointerException.class); + modelManager.hasEmail(null); + } + + @Test + public void hasEmail_emailNotInEmailModel_returnsFalse() { + assertFalse(modelManager.hasEmail(MEETING_EMAIL.getSubject())); + } + + @Test + public void hasEmail_emailInEmailModel_returnsTrue() { + modelManager.saveComposedEmail(MEETING_EMAIL); + TestCase.assertTrue(modelManager.hasEmail(MEETING_EMAIL.getSubject())); + } + + @Test + public void getExistingEmails_modifySet_throwsUnsupportedOperationException() { + thrown.expect(UnsupportedOperationException.class); + modelManager.getExistingEmails().add("Hello"); + } + @Test public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException() { thrown.expect(UnsupportedOperationException.class); @@ -81,5 +108,10 @@ public void equals() { UserPrefs differentUserPrefs = new UserPrefs(); differentUserPrefs.setAddressBookFilePath(Paths.get("differentFilePath")); assertTrue(modelManager.equals(new ModelManager(addressBook, differentUserPrefs))); + + // different emailModel -> returns false + Email validEmail = new DefaultEmailBuilder().build(); + modelManager.saveComposedEmail(validEmail); + assertFalse(modelManager.equals(new ModelManager(addressBook, userPrefs))); } } From ffa6d8898653a79d9788a2f57952089f21ddc1c2 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Tue, 6 Nov 2018 18:08:27 +0800 Subject: [PATCH 22/32] Fixed codacy issue --- src/test/java/seedu/address/model/ModelManagerTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/seedu/address/model/ModelManagerTest.java b/src/test/java/seedu/address/model/ModelManagerTest.java index 05fe17a3b68d..3c67266ead6f 100644 --- a/src/test/java/seedu/address/model/ModelManagerTest.java +++ b/src/test/java/seedu/address/model/ModelManagerTest.java @@ -15,7 +15,6 @@ import org.junit.rules.ExpectedException; import org.simplejavamail.email.Email; -import junit.framework.TestCase; import seedu.address.model.person.NameContainsKeywordsPredicate; import seedu.address.model.person.Person; import seedu.address.testutil.AddressBookBuilder; @@ -44,6 +43,7 @@ public void hasPerson_personInAddressBook_returnsTrue() { assertTrue(modelManager.hasPerson(ALICE)); } + //@@author EatOrBeEaten @Test public void hasEmail_nullEmail_throwsNullPointerException() { thrown.expect(NullPointerException.class); @@ -58,7 +58,7 @@ public void hasEmail_emailNotInEmailModel_returnsFalse() { @Test public void hasEmail_emailInEmailModel_returnsTrue() { modelManager.saveComposedEmail(MEETING_EMAIL); - TestCase.assertTrue(modelManager.hasEmail(MEETING_EMAIL.getSubject())); + assertTrue(modelManager.hasEmail(MEETING_EMAIL.getSubject())); } @Test @@ -66,6 +66,7 @@ public void getExistingEmails_modifySet_throwsUnsupportedOperationException() { thrown.expect(UnsupportedOperationException.class); modelManager.getExistingEmails().add("Hello"); } + //@@author @Test public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException() { From 17fa23e2faaf78dbd61e3f4ddb3b0832e5a078aa Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Tue, 6 Nov 2018 21:39:17 +0800 Subject: [PATCH 23/32] Added test data for EmailDirStorageTest --- .../Meeting this Friday.eml | 29 +++++++++++++++++++ .../Meeting this Saturday.eml | 28 ++++++++++++++++++ src/test/data/EmailDirStorageTest/Meeting.eml | 29 +++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 src/test/data/EmailDirStorageTest/Meeting this Friday.eml create mode 100644 src/test/data/EmailDirStorageTest/Meeting this Saturday.eml create mode 100644 src/test/data/EmailDirStorageTest/Meeting.eml diff --git a/src/test/data/EmailDirStorageTest/Meeting this Friday.eml b/src/test/data/EmailDirStorageTest/Meeting this Friday.eml new file mode 100644 index 000000000000..7be6725950a1 --- /dev/null +++ b/src/test/data/EmailDirStorageTest/Meeting this Friday.eml @@ -0,0 +1,29 @@ +Date: Mon, 5 Nov 2018 01:23:57 +0800 (SRET) +From: johndoe@example.com +Reply-To: johndoe@example.com +To: alex@gmail.com, betty@gmail.com, johns@example.com, d@gmail.com, + charles@gmail.com +Message-ID: <1603502867.3.1541348819045@[172.31.118.157]> +Subject: Meeting this Friday +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="----=_Part_0_493625986.1541352237174" + +------=_Part_0_493625986.1541352237174 +Content-Type: multipart/related; + boundary="----=_Part_1_115279044.1541352237175" + +------=_Part_1_115279044.1541352237175 +Content-Type: multipart/alternative; + boundary="----=_Part_2_1242214460.1541352237175" + +------=_Part_2_1242214460.1541352237175 +Content-Type: text/html; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + +Dear All

There=E2=80=99s a meeting this friday.

John Doe +------=_Part_2_1242214460.1541352237175-- + +------=_Part_1_115279044.1541352237175-- + +------=_Part_0_493625986.1541352237174-- diff --git a/src/test/data/EmailDirStorageTest/Meeting this Saturday.eml b/src/test/data/EmailDirStorageTest/Meeting this Saturday.eml new file mode 100644 index 000000000000..ab4485f56fef --- /dev/null +++ b/src/test/data/EmailDirStorageTest/Meeting this Saturday.eml @@ -0,0 +1,28 @@ +Date: Sat, 27 Oct 2018 12:23:11 +0800 (SRET) +From: johndoe@example.com +To: charles@gmail.com, d@gmail.com, alex@gmail.com, johns@example.com, + betty@gmail.com +Message-ID: <1729586336.7.1540614191678@[172.31.119.236]> +Subject: Meeting this Saturday +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="----=_Part_4_948919235.1540614191672" + +------=_Part_4_948919235.1540614191672 +Content-Type: multipart/related; + boundary="----=_Part_5_614520046.1540614191672" + +------=_Part_5_614520046.1540614191672 +Content-Type: multipart/alternative; + boundary="----=_Part_6_845923364.1540614191672" + +------=_Part_6_845923364.1540614191672 +Content-Type: text/html; charset="UTF-8" +Content-Transfer-Encoding: 7bit + +Dear All

Remember our meeting this saturday.

John +------=_Part_6_845923364.1540614191672-- + +------=_Part_5_614520046.1540614191672-- + +------=_Part_4_948919235.1540614191672-- diff --git a/src/test/data/EmailDirStorageTest/Meeting.eml b/src/test/data/EmailDirStorageTest/Meeting.eml new file mode 100644 index 000000000000..d1a74d6ca39e --- /dev/null +++ b/src/test/data/EmailDirStorageTest/Meeting.eml @@ -0,0 +1,29 @@ +Date: Tue, 6 Nov 2018 02:36:54 +0800 (SRET) +From: johndoe@example.com +Reply-To: johndoe@example.com +To: alex@gmail.com, johns@example.com, d@gmail.com, charles@gmail.com, + betty@gmail.com +Message-ID: <352336373.3.1540718892590@[172.31.119.236]> +Subject: Meeting +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="----=_Part_0_2135353666.1541443014095" + +------=_Part_0_2135353666.1541443014095 +Content-Type: multipart/related; + boundary="----=_Part_1_237517624.1541443014096" + +------=_Part_1_237517624.1541443014096 +Content-Type: multipart/alternative; + boundary="----=_Part_2_465288242.1541443014096" + +------=_Part_2_465288242.1541443014096 +Content-Type: text/html; charset="UTF-8" +Content-Transfer-Encoding: 7bit + +Dear All

Remember our meeting this friday.

John +------=_Part_2_465288242.1541443014096-- + +------=_Part_1_237517624.1541443014096-- + +------=_Part_0_2135353666.1541443014095-- From 64300817eb64221b53fb2f969b316ecaf47e406a Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Tue, 6 Nov 2018 21:39:37 +0800 Subject: [PATCH 24/32] Added EmailDirStorageTest --- .../address/storage/EmailDirStorageTest.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/test/java/seedu/address/storage/EmailDirStorageTest.java diff --git a/src/test/java/seedu/address/storage/EmailDirStorageTest.java b/src/test/java/seedu/address/storage/EmailDirStorageTest.java new file mode 100644 index 000000000000..7a48c1db96a6 --- /dev/null +++ b/src/test/java/seedu/address/storage/EmailDirStorageTest.java @@ -0,0 +1,32 @@ +package seedu.address.storage; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Set; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; + +//@@author EatOrBeEaten +public class EmailDirStorageTest { + + private static final Path TEST_DATA_FOLDER = Paths.get("src", "test", "data", "EmailDirStorageTest"); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Rule + public TemporaryFolder testFolder = new TemporaryFolder(); + + @Test + public void readEmailFiles_nullFilePath_throwsNullPointerException() throws Exception { + thrown.expect(NullPointerException.class); + readEmailFiles(null); + } + + private Set readEmailFiles(String filePath) { + return new EmailDirStorage(Paths.get(filePath)).readEmailFiles(Paths.get(filePath)); + } +} From 78bafa919bc77d75f4533cdfae1d5ac92c0a4444 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Wed, 7 Nov 2018 00:06:08 +0800 Subject: [PATCH 25/32] Added unit tests to EmailDirStorageTest --- .../address/storage/EmailDirStorageTest.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/test/java/seedu/address/storage/EmailDirStorageTest.java b/src/test/java/seedu/address/storage/EmailDirStorageTest.java index 7a48c1db96a6..71d9db44e109 100644 --- a/src/test/java/seedu/address/storage/EmailDirStorageTest.java +++ b/src/test/java/seedu/address/storage/EmailDirStorageTest.java @@ -1,13 +1,20 @@ package seedu.address.storage; +import static org.junit.Assert.assertEquals; + import java.nio.file.Path; import java.nio.file.Paths; +import java.util.HashSet; import java.util.Set; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; +import org.simplejavamail.email.Email; + +import seedu.address.model.EmailModel; +import seedu.address.testutil.DefaultEmailBuilder; //@@author EatOrBeEaten public class EmailDirStorageTest { @@ -26,7 +33,32 @@ public void readEmailFiles_nullFilePath_throwsNullPointerException() throws Exce readEmailFiles(null); } + @Test + public void readEmailFiles_missingDirectory_returnsEmptySet() { + assertEquals(readEmailFiles("nonExistentDirectory"), new HashSet<>()); + } + + @Test + public void readEmailFiles_emptyDirectory_returnsEmptySet() { + String filePath = testFolder.getRoot().toPath().toString(); + assertEquals(readEmailFiles(filePath), new HashSet<>()); + } + private Set readEmailFiles(String filePath) { return new EmailDirStorage(Paths.get(filePath)).readEmailFiles(Paths.get(filePath)); } + +// @Test +// public void loadEmail_allInOrder_success() throws Exception { +// Email validEmail = new DefaultEmailBuilder().build(); +// EmailModel emailModel = new EmailModel(); +// emailModel.saveComposedEmail(validEmail); +// Path filePath = testFolder.getRoot().toPath(); +// EmailDirStorage emailDirStorage = new EmailDirStorage(filePath); +// +// // Save in a new email and read back +// emailDirStorage.saveEmail(emailModel); +// Email readBack = emailDirStorage.loadEmail(validEmail.getSubject()); +// assertEquals(validEmail, readBack); +// } } From ec235059929d2efa20518f84cf96b3046c5a4823 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Wed, 7 Nov 2018 00:12:32 +0800 Subject: [PATCH 26/32] Removed test data for EmailDirStorageTest --- .../Meeting this Friday.eml | 29 ------------------- .../Meeting this Saturday.eml | 28 ------------------ src/test/data/EmailDirStorageTest/Meeting.eml | 29 ------------------- 3 files changed, 86 deletions(-) delete mode 100644 src/test/data/EmailDirStorageTest/Meeting this Friday.eml delete mode 100644 src/test/data/EmailDirStorageTest/Meeting this Saturday.eml delete mode 100644 src/test/data/EmailDirStorageTest/Meeting.eml diff --git a/src/test/data/EmailDirStorageTest/Meeting this Friday.eml b/src/test/data/EmailDirStorageTest/Meeting this Friday.eml deleted file mode 100644 index 7be6725950a1..000000000000 --- a/src/test/data/EmailDirStorageTest/Meeting this Friday.eml +++ /dev/null @@ -1,29 +0,0 @@ -Date: Mon, 5 Nov 2018 01:23:57 +0800 (SRET) -From: johndoe@example.com -Reply-To: johndoe@example.com -To: alex@gmail.com, betty@gmail.com, johns@example.com, d@gmail.com, - charles@gmail.com -Message-ID: <1603502867.3.1541348819045@[172.31.118.157]> -Subject: Meeting this Friday -MIME-Version: 1.0 -Content-Type: multipart/mixed; - boundary="----=_Part_0_493625986.1541352237174" - -------=_Part_0_493625986.1541352237174 -Content-Type: multipart/related; - boundary="----=_Part_1_115279044.1541352237175" - -------=_Part_1_115279044.1541352237175 -Content-Type: multipart/alternative; - boundary="----=_Part_2_1242214460.1541352237175" - -------=_Part_2_1242214460.1541352237175 -Content-Type: text/html; charset="UTF-8" -Content-Transfer-Encoding: quoted-printable - -Dear All

There=E2=80=99s a meeting this friday.

John Doe -------=_Part_2_1242214460.1541352237175-- - -------=_Part_1_115279044.1541352237175-- - -------=_Part_0_493625986.1541352237174-- diff --git a/src/test/data/EmailDirStorageTest/Meeting this Saturday.eml b/src/test/data/EmailDirStorageTest/Meeting this Saturday.eml deleted file mode 100644 index ab4485f56fef..000000000000 --- a/src/test/data/EmailDirStorageTest/Meeting this Saturday.eml +++ /dev/null @@ -1,28 +0,0 @@ -Date: Sat, 27 Oct 2018 12:23:11 +0800 (SRET) -From: johndoe@example.com -To: charles@gmail.com, d@gmail.com, alex@gmail.com, johns@example.com, - betty@gmail.com -Message-ID: <1729586336.7.1540614191678@[172.31.119.236]> -Subject: Meeting this Saturday -MIME-Version: 1.0 -Content-Type: multipart/mixed; - boundary="----=_Part_4_948919235.1540614191672" - -------=_Part_4_948919235.1540614191672 -Content-Type: multipart/related; - boundary="----=_Part_5_614520046.1540614191672" - -------=_Part_5_614520046.1540614191672 -Content-Type: multipart/alternative; - boundary="----=_Part_6_845923364.1540614191672" - -------=_Part_6_845923364.1540614191672 -Content-Type: text/html; charset="UTF-8" -Content-Transfer-Encoding: 7bit - -Dear All

Remember our meeting this saturday.

John -------=_Part_6_845923364.1540614191672-- - -------=_Part_5_614520046.1540614191672-- - -------=_Part_4_948919235.1540614191672-- diff --git a/src/test/data/EmailDirStorageTest/Meeting.eml b/src/test/data/EmailDirStorageTest/Meeting.eml deleted file mode 100644 index d1a74d6ca39e..000000000000 --- a/src/test/data/EmailDirStorageTest/Meeting.eml +++ /dev/null @@ -1,29 +0,0 @@ -Date: Tue, 6 Nov 2018 02:36:54 +0800 (SRET) -From: johndoe@example.com -Reply-To: johndoe@example.com -To: alex@gmail.com, johns@example.com, d@gmail.com, charles@gmail.com, - betty@gmail.com -Message-ID: <352336373.3.1540718892590@[172.31.119.236]> -Subject: Meeting -MIME-Version: 1.0 -Content-Type: multipart/mixed; - boundary="----=_Part_0_2135353666.1541443014095" - -------=_Part_0_2135353666.1541443014095 -Content-Type: multipart/related; - boundary="----=_Part_1_237517624.1541443014096" - -------=_Part_1_237517624.1541443014096 -Content-Type: multipart/alternative; - boundary="----=_Part_2_465288242.1541443014096" - -------=_Part_2_465288242.1541443014096 -Content-Type: text/html; charset="UTF-8" -Content-Transfer-Encoding: 7bit - -Dear All

Remember our meeting this friday.

John -------=_Part_2_465288242.1541443014096-- - -------=_Part_1_237517624.1541443014096-- - -------=_Part_0_2135353666.1541443014095-- From 0ef750f3ea833a4e23378986bfea3be26f510557 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Wed, 7 Nov 2018 00:12:40 +0800 Subject: [PATCH 27/32] Fixed checkstyle errors --- .../address/storage/EmailDirStorageTest.java | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/test/java/seedu/address/storage/EmailDirStorageTest.java b/src/test/java/seedu/address/storage/EmailDirStorageTest.java index 71d9db44e109..167543f4b67f 100644 --- a/src/test/java/seedu/address/storage/EmailDirStorageTest.java +++ b/src/test/java/seedu/address/storage/EmailDirStorageTest.java @@ -2,7 +2,6 @@ import static org.junit.Assert.assertEquals; -import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashSet; import java.util.Set; @@ -11,16 +10,10 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; -import org.simplejavamail.email.Email; - -import seedu.address.model.EmailModel; -import seedu.address.testutil.DefaultEmailBuilder; //@@author EatOrBeEaten public class EmailDirStorageTest { - private static final Path TEST_DATA_FOLDER = Paths.get("src", "test", "data", "EmailDirStorageTest"); - @Rule public ExpectedException thrown = ExpectedException.none(); @@ -48,17 +41,18 @@ private Set readEmailFiles(String filePath) { return new EmailDirStorage(Paths.get(filePath)).readEmailFiles(Paths.get(filePath)); } -// @Test -// public void loadEmail_allInOrder_success() throws Exception { -// Email validEmail = new DefaultEmailBuilder().build(); -// EmailModel emailModel = new EmailModel(); -// emailModel.saveComposedEmail(validEmail); -// Path filePath = testFolder.getRoot().toPath(); -// EmailDirStorage emailDirStorage = new EmailDirStorage(filePath); -// -// // Save in a new email and read back -// emailDirStorage.saveEmail(emailModel); -// Email readBack = emailDirStorage.loadEmail(validEmail.getSubject()); -// assertEquals(validEmail, readBack); -// } + // @Test + // public void loadEmail_allInOrder_success() throws Exception { + // Email validEmail = new DefaultEmailBuilder().build(); + // EmailModel emailModel = new EmailModel(); + // emailModel.saveComposedEmail(validEmail); + // Path filePath = testFolder.getRoot().toPath(); + // EmailDirStorage emailDirStorage = new EmailDirStorage(filePath); + // + // // Save in a new email and read back + // emailDirStorage.saveEmail(emailModel); + // Email readBack = emailDirStorage.loadEmail(validEmail.getSubject()); + // assertEquals(validEmail, readBack); + // } + } From 99611b3ae83ef2fc633f94e98c6a78708d055fed Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Wed, 7 Nov 2018 01:16:20 +0800 Subject: [PATCH 28/32] Added EmailUtil --- .../seedu/address/testutil/EmailUtil.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/test/java/seedu/address/testutil/EmailUtil.java diff --git a/src/test/java/seedu/address/testutil/EmailUtil.java b/src/test/java/seedu/address/testutil/EmailUtil.java new file mode 100644 index 000000000000..9b07ab9c7981 --- /dev/null +++ b/src/test/java/seedu/address/testutil/EmailUtil.java @@ -0,0 +1,35 @@ +package seedu.address.testutil; + +//@@author EatOrBeEaten + +import static seedu.address.logic.parser.CliSyntax.PREFIX_CONTENT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_FROM; +import static seedu.address.logic.parser.CliSyntax.PREFIX_SUBJECT; + +import org.simplejavamail.email.Email; + +import seedu.address.logic.commands.ComposeEmailListCommand; + +/** + * A utility class for Email + */ +public class EmailUtil { + + /** + * Returns a ComposeEmailListCommand string for adding the {@code email}. + */ + public static String getComposeEmailListCommand(Email email) { + return ComposeEmailListCommand.COMMAND_WORD + " " + getComposeEmailListDetails(email); + } + + /** + * Returns the part of command stirng for the given {@code email}'s details for ComposeEmailListCommand. + */ + public static String getComposeEmailListDetails(Email email) { + StringBuilder sb = new StringBuilder(); + sb.append(PREFIX_FROM + email.getFromRecipient().getAddress() + " "); + sb.append(PREFIX_SUBJECT + email.getSubject() + " "); + sb.append(PREFIX_CONTENT + email.getHTMLText() + " "); + return sb.toString(); + } +} From 287d9a18de142ffd934fda0785bb65190390982c Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Sun, 11 Nov 2018 20:18:43 +0800 Subject: [PATCH 29/32] Moved raising EmailViewEvent to ModelManager --- src/main/java/seedu/address/model/Model.java | 7 ++++++- .../java/seedu/address/model/ModelManager.java | 15 +++++++++++++++ .../seedu/address/storage/StorageManager.java | 3 --- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index a483f71b2bb4..477d6c23c7a2 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -204,10 +204,15 @@ public interface Model { void saveEmail(Email email); /** - * Saves a newly composed email to the EmailModel. + * Saves a newly composed email to the EmailModel, and display it on BrowserPanel. */ void saveComposedEmail(Email email); + /** + * Saves a newly composed email to the EmailModel. + */ + void saveComposedEmailWithoutDisplay(Email email); + /** * Deletes an existing email from EmailModel. */ diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index aadf843c5a67..220314bbcb14 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -503,6 +503,12 @@ public void saveComposedEmail(Email email) { indicateEmailSaved(); } + @Override + public void saveComposedEmailWithoutDisplay(Email email) { + emailModel.saveComposedEmail(email); + indicateEmailSavedWithoutDisplay(); + } + @Override public void deleteEmail(String fileName) { emailModel.removeFromExistingEmails(fileName); @@ -518,8 +524,17 @@ public boolean hasEmail(String fileName) { /** * Raises an event to indicate that a new email has been saved to EmailModel. */ + private void indicateEmailSavedWithoutDisplay() { + raise(new EmailSavedEvent(emailModel)); + } + + /** + * Raises an event to indicate that a new email has been saved to EmailModel, and displays it on the BrowserPanel. + */ private void indicateEmailSaved() { raise(new EmailSavedEvent(emailModel)); + raise(new ToggleBrowserPlaceholderEvent(ToggleBrowserPlaceholderEvent.BROWSER_PANEL)); + raise(new EmailViewEvent(emailModel)); } @Override diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/seedu/address/storage/StorageManager.java index 06b2ea6e9f30..9f0290d01d5a 100644 --- a/src/main/java/seedu/address/storage/StorageManager.java +++ b/src/main/java/seedu/address/storage/StorageManager.java @@ -34,7 +34,6 @@ import seedu.address.commons.events.storage.EmailLoadEvent; import seedu.address.commons.events.storage.ImageReadingExceptionEvent; import seedu.address.commons.events.ui.EmailNotFoundEvent; -import seedu.address.commons.events.ui.EmailViewEvent; import seedu.address.commons.events.ui.ToggleBrowserPlaceholderEvent; import seedu.address.commons.exceptions.DataConversionException; import seedu.address.commons.util.StringUtil; @@ -225,8 +224,6 @@ public void handleEmailSavedEvent(EmailSavedEvent event) { logger.info(LogsCenter.getEventHandlingLogMessage(event, "Email composed, saving to directory.")); try { saveEmail(event.data); - raise(new ToggleBrowserPlaceholderEvent(ToggleBrowserPlaceholderEvent.BROWSER_PANEL)); - raise(new EmailViewEvent(event.data)); } catch (IOException e) { raise(new DataSavingExceptionEvent(e)); } From df94dadb25413e2b6c6acfc770ff1434a32fdabd Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Sun, 11 Nov 2018 20:19:11 +0800 Subject: [PATCH 30/32] Added saveComposedEmailWithoutDisplay to ModelStub in AddCommandTest --- .../java/seedu/address/logic/commands/AddCommandTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/java/seedu/address/logic/commands/AddCommandTest.java b/src/test/java/seedu/address/logic/commands/AddCommandTest.java index 706f930fcec0..346d3fde0620 100644 --- a/src/test/java/seedu/address/logic/commands/AddCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddCommandTest.java @@ -261,6 +261,11 @@ public void saveComposedEmail(Email email) { throw new AssertionError("This method should not be called."); } + @Override + public void saveComposedEmailWithoutDisplay(Email email) { + throw new AssertionError("This method should not be called."); + } + @Override public void deleteEmail(String fileName) { throw new AssertionError("This method should not be called."); From 86c000601d2994121c931861441dc62c1d5abbc6 Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Sun, 11 Nov 2018 20:20:23 +0800 Subject: [PATCH 31/32] Added DeleteEmailCommandSystemTest --- src/test/java/seedu/address/TestApp.java | 6 ++ .../systemtests/AddressBookSystemTest.java | 5 ++ .../DeleteEmailCommandSystemTest.java | 79 +++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 src/test/java/systemtests/DeleteEmailCommandSystemTest.java diff --git a/src/test/java/seedu/address/TestApp.java b/src/test/java/seedu/address/TestApp.java index e8802e106142..6e216e1a0ef3 100644 --- a/src/test/java/seedu/address/TestApp.java +++ b/src/test/java/seedu/address/TestApp.java @@ -4,6 +4,8 @@ import java.nio.file.Path; import java.util.function.Supplier; +import org.simplejavamail.email.Email; + import javafx.stage.Screen; import javafx.stage.Stage; import seedu.address.commons.core.Config; @@ -118,4 +120,8 @@ private void createDataFileWithData(T data, Path filePath) { throw new RuntimeException(e); } } + + public void saveComposedEmailWithoutDisplay(Email email) { + model.saveComposedEmailWithoutDisplay(email); + } } diff --git a/src/test/java/systemtests/AddressBookSystemTest.java b/src/test/java/systemtests/AddressBookSystemTest.java index 4ebb708445a6..dbb8ceba2bc0 100644 --- a/src/test/java/systemtests/AddressBookSystemTest.java +++ b/src/test/java/systemtests/AddressBookSystemTest.java @@ -22,6 +22,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; +import org.simplejavamail.email.Email; import guitests.guihandles.BrowserPanelHandle; import guitests.guihandles.CommandBoxHandle; @@ -291,4 +292,8 @@ private void assertApplicationStartingStateIsCorrect() { protected Model getModel() { return testApp.getModel(); } + + protected void saveComposedEmailWithoutDisplay(Email email) { + testApp.saveComposedEmailWithoutDisplay(email); + } } diff --git a/src/test/java/systemtests/DeleteEmailCommandSystemTest.java b/src/test/java/systemtests/DeleteEmailCommandSystemTest.java new file mode 100644 index 000000000000..20753efa9c81 --- /dev/null +++ b/src/test/java/systemtests/DeleteEmailCommandSystemTest.java @@ -0,0 +1,79 @@ +package systemtests; + +import static seedu.address.commons.core.Messages.MESSAGE_EMAIL_DOES_NOT_EXIST; +import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND; +import static seedu.address.testutil.TypicalEmails.CAMP_EMAIL; + +import org.junit.Test; + +import seedu.address.commons.core.Messages; +import seedu.address.logic.commands.DeleteEmailCommand; +import seedu.address.model.Model; + +public class DeleteEmailCommandSystemTest extends AddressBookSystemTest { + + private static final String MESSAGE_INVALID_DELETE_EMAIL_COMMAND_FORMAT = + String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, DeleteEmailCommand.MESSAGE_USAGE); + + @Test + public void delete() { + + /* Case: delete the first email in the list, command with leading spaces and trailing spaces -> deleted */ + Model expectedModel = getModel(); + saveComposedEmailWithoutDisplay(CAMP_EMAIL); + String command = " " + DeleteEmailCommand.COMMAND_WORD + " " + CAMP_EMAIL.getSubject(); + String expectedResultMessage = String.format(DeleteEmailCommand.MESSAGE_SUCCESS, CAMP_EMAIL.getSubject()); + assertCommandSuccess(command, expectedModel, expectedResultMessage); + + /* ----------------------------- Performing invalid delete email operation -----------------------------------*/ + + /* Case: email does not exist -> rejected */ + command = DeleteEmailCommand.COMMAND_WORD + " nonExistentEmailSubject"; + assertCommandFailure(command, String.format(MESSAGE_EMAIL_DOES_NOT_EXIST, "nonExistentEmailSubject")); + + /* Case: invalid argument (blank space) -> rejected */ + assertCommandFailure(DeleteEmailCommand.COMMAND_WORD + " ", MESSAGE_INVALID_DELETE_EMAIL_COMMAND_FORMAT); + + /* Case: mixed case command word -> rejected */ + assertCommandFailure("dElEte_EmAil Meeting", MESSAGE_UNKNOWN_COMMAND); + } + + /** + * Executes {@code command} and in addition,
+ * 1. Asserts that the command box displays an empty string.
+ * 2. Asserts that the result display box displays {@code expectedResultMessage}.
+ * 3. Asserts that the browser url and selected card remains unchanged.
+ * 4. Asserts that the status bar's sync status changes.
+ * 5. Asserts that the command box has the default style class.
+ * Verifications 1 and 2 are performed by + * {@code AddressBookSystemTest#assertApplicationDisplaysExpected(String, String, Model)}. + * @see AddressBookSystemTest#assertApplicationDisplaysExpected(String, String, Model) + */ + private void assertCommandSuccess(String command, Model expectedModel, String expectedResultMessage) { + executeCommand(command); + assertApplicationDisplaysExpected("", expectedResultMessage, expectedModel); + assertSelectedCardUnchanged(); + assertCommandBoxShowsDefaultStyle(); + assertStatusBarUnchanged(); + } + + /** + * Executes {@code command} and in addition,
+ * 1. Asserts that the command box displays {@code command}.
+ * 2. Asserts that result display box displays {@code expectedResultMessage}.
+ * 3. Asserts that the browser url, selected card and status bar remain unchanged.
+ * 4. Asserts that the command box has the error style.
+ * Verifications 1 and 2 are performed by + * {@code AddressBookSystemTest#assertApplicationDisplaysExpected(String, String, Model)}.
+ * @see AddressBookSystemTest#assertApplicationDisplaysExpected(String, String, Model) + */ + private void assertCommandFailure(String command, String expectedResultMessage) { + Model expectedModel = getModel(); + + executeCommand(command); + assertApplicationDisplaysExpected(command, expectedResultMessage, expectedModel); + assertSelectedCardUnchanged(); + assertCommandBoxShowsErrorStyle(); + assertStatusBarUnchanged(); + } +} From ba455ec1d8c7505bc2473142f06a5056e18a8f3e Mon Sep 17 00:00:00 2001 From: Kok Yuan Date: Sun, 11 Nov 2018 20:50:21 +0800 Subject: [PATCH 32/32] Added method to modelstub in CreateCcaCommandTest --- .../seedu/address/logic/commands/CreateCcaCommandTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/java/seedu/address/logic/commands/CreateCcaCommandTest.java b/src/test/java/seedu/address/logic/commands/CreateCcaCommandTest.java index 8eba15f26717..287c39aefc60 100644 --- a/src/test/java/seedu/address/logic/commands/CreateCcaCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/CreateCcaCommandTest.java @@ -284,6 +284,11 @@ public void saveComposedEmail(Email email) { throw new AssertionError("This method should not be called."); } + @Override + public void saveComposedEmailWithoutDisplay(Email email) { + throw new AssertionError("This method should not be called."); + } + @Override public void deleteEmail(String fileName) { throw new AssertionError("This method should not be called.");