Follow-up to #2804557: Iterate and render MultipartMessage parts

Problem/Motivation

Mail display tests are currently in testEmailDisplay() method. That means they can grow very easily.

Proposed resolution

Make them per mail example (plain/text email, HTML email etc).

Remaining tasks

User interface changes

API changes

Data model changes

CommentFileSizeAuthor
#33 write_mail_display-2807733-33.patch50.17 KBtduong
#33 interdiff-2807733-29-33.txt7.85 KBtduong
#29 write_mail_display-2807733-29.patch55.32 KBtduong
#29 interdiff-2807733-27-29.txt22.78 KBtduong
#27 write_mail_display-2807733-27.patch38.52 KBtduong
#25 write_mail_display-2807733-25.patch25.02 KBtduong
#23 interdiff-2807733-20-23.txt18.52 KBtoncic
#23 write_mail_display-2807733-23.patch19.37 KBtoncic
#20 interdiff-2807733-17-20.txt11.44 KBtoncic
#20 write_mail_display-2807733-20.patch13.73 KBtoncic
#17 interdiff-2807733-15-17.txt868 bytestoncic
#17 write_mail_display-2807733-17.patch9.66 KBtoncic
#15 write_mail_display-2807733-13.patch9.66 KBtoncic
#13 interdiff-2807733-11-13.txt3.7 KBtoncic
#13 write_mail_display-2807733-11.patch13.6 KBtoncic
#11 interdiff-2807733-9-11.txt14.14 KBtoncic
#11 write_mail_display-2807733-11.patch13.6 KBtoncic
#9 interdiff-2807733-5-9.txt1.41 KBtbonomelli
#9 write_mail_display-2807733-9.patch2.57 KBtbonomelli
#5 test-2807733-5.patch2.83 KBModernMantra
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mbovan created an issue. See original summary.

mbovan’s picture

Title: Write mail dispaly tests per example » Write mail display tests per example

The issue title update.

miro_dietiker’s picture

I guess it will be an own test class.

And yes, we need:
- specific tests of individual parts, one per part, Unit test.
- multiple tests that each process an example message and assert expectations.

miro_dietiker’s picture

So we discussed how to display mails in #2804587: Create mail display mock-ups

We won't need an element per part type.
Instead the message will be an intelligent element containing 4 parts: Header, Body, Attachments, Unknown.

The tests will focus on those areas.
One test for the headers will process multiple variations of from / to / subject messages to make sure single / multiple recipients or such with or without name are well displayed. Also expansion of header area is possible.
Some other test will process multiple mails: a plaintext, one with alternate (plaintext AND html), one with HTML only. And the body needs to display it properly.
Some other test will focus on multiple attachment variants. With short, long labels, containing special characters, cover case of attachment deletion due to oversize, and inline image as attachments
One test will introduce unknown parts that are not considered with the elements mentioned above. They need to get visible. The regular cases need to check that the unknown area is not visible.
Some later test will focus on inline image coverage (not yet supported).

After started with the basics, we should move the test coverage expectations into the corresponding issues. Until this happened, the issue will stay back open.

ModernMantra’s picture

Status: Active » Needs review
FileSize
2.83 KB

Status: Needs review » Needs work

The last submitted patch, 5: test-2807733-5.patch, failed testing.

ModernMantra’s picture

Status: Needs work » Needs review

There have been some unexpected CI errors, with re-adding test seems everything is ok. Setting back to needs review :)

miro_dietiker’s picture

Status: Needs review » Needs work
  1. +++ b/tests/modules/inmail_test/eml/multiple-header-fields.eml
    @@ -0,0 +1,32 @@
    +Cc: Someone Else <inmail_other@example.com>From: Nancy <nancy@example.com>
    

    Uh?

  2. +++ b/tests/modules/inmail_test/eml/multiple-header-fields.eml
    @@ -0,0 +1,32 @@
    +Bcc: Big Brother <bigbrother@example.com>
    

    We as recipient will never see a mail with Bcc in header. The MTA is expanding Bcc recipient sand by definition remove the header from the mail before sending it out.

  3. +++ b/tests/modules/inmail_test/eml/multiple-header-fields.eml
    @@ -0,0 +1,32 @@
    +Content-Type: text/plain; charset=UTF-8
    +To: bounces+user=example.org@example.com
    +Cc: Senator John <senator_john@usa.gov.com>
    +From: hello_world@example.com
    +Subject: I am currently working
    +Date: Wed, 8 Jan 2014 13:42:55 +0100
    ...
    +--047d7bf0d0f694271f0505eb5984
    +Content-Type: text/html; charset=UTF-8
    +Date: Wed, 08 Jan 2014 13:42:18 +0100
    +From: Arild Matsson <admin@example.com>
    +To: replica@example.com
    +Subject: Replica
    

    Parts in multipart mails like this (especially type text/plain or text/html) are never mails and thus never have a From / To / Cc header.

    Only the mail header itself needs those fields. The mockup shows that we will remove that "From / To" display per part and display parts completely different.

tbonomelli’s picture

Assigned: mbovan » tbonomelli
Status: Needs work » Needs review
FileSize
2.57 KB
1.41 KB

Removed wrong headers.

miro_dietiker’s picture

Status: Needs review » Needs work

Now the problem is:
- See #3, if we split, it should be a separate test class, not only a test method.
- The existing mail display tests also need to be moved here.

+++ b/tests/modules/inmail_test/eml/multiple-header-fields.eml
@@ -0,0 +1,26 @@
+From: Arild Matsson <arild@masked1.se>
...
+From: Nancy <nancy@example.com>

This is invalid.

+++ b/src/Tests/IntegrationTest.php
@@ -189,6 +189,31 @@ class IntegrationTest extends WebTestBase {
+    $this->assertText('Email display');

Most importantly also assert the header fields. Or negatively assert them if they should be missing.

And it should be multiple example mails, with variable cases. And most importantly we need to cover varying cases with multiple recipient (to, cc) addresses.

toncic’s picture

Status: Needs work » Needs review
FileSize
13.6 KB
14.14 KB

Made new test class and move relevant functions there. Also added new helper method. I need to change xpath in helper function and check the order of fields.

I don't know why but git says that I renamed the old class IntegrationTest instead of creating new MultipartMessageHeaderTest.

miro_dietiker’s picture

Status: Needs review » Needs work
+++ b/src/Tests/MultipartMessageHeaderTest.php
@@ -91,14 +91,7 @@ class IntegrationTest extends WebTestBase {
+    $this->assertHeaderFields($message);

@@ -135,130 +127,44 @@ class IntegrationTest extends WebTestBase {
+ public function assertHeaderFields($message) {

That's too much abstracted away.
In maximum we can offer a assertHeaderField($name, $value) and assertNoHeaderField($name) and call them based on our expectations.

+++ b/src/Tests/IntegrationTest.php
similarity index 53%
copy from src/Tests/IntegrationTest.php

copy from src/Tests/IntegrationTest.php
copy to src/Tests/MultipartMessageHeaderTest.php

No it says you started with a copy and then only indicates changes to it. That makes patches smaller and easier to review.

toncic’s picture

Assigned: tbonomelli » toncic
Status: Needs work » Needs review
FileSize
13.6 KB
3.7 KB

Added three new function, two as @miro suggested and one more to check if the value is on right field.

Status: Needs review » Needs work

The last submitted patch, 13: write_mail_display-2807733-11.patch, failed testing.

toncic’s picture

Status: Needs work » Needs review
FileSize
9.66 KB

Wrong patch.

johnchque’s picture

Status: Needs review » Needs work

Small thing:

+++ b/src/Tests/MultipartMessageHeaderTest.php
@@ -0,0 +1,225 @@
+    $event_id = db_query_range('SELECT event_id FROM {past_event} WHERE machine_name = :machine_name ORDER BY event_id DESC', 0, 1, array(':machine_name' => $machine_name))->fetchField();

[] instead of array.

toncic’s picture

Status: Needs work » Needs review
FileSize
9.66 KB
868 bytes

Changed to use new syntax for array.

miro_dietiker’s picture

Status: Needs review » Needs work
  1. +++ b/src/Tests/MultipartMessageHeaderTest.php
    @@ -0,0 +1,225 @@
    +use Drupal\search_api\Tests\WebTestBase;
    

    search_api?!

  2. +++ b/src/Tests/MultipartMessageHeaderTest.php
    @@ -0,0 +1,225 @@
    +    // Test "teaser" view mode of Inmail message element.
    ...
    +    $user = $this->drupalCreateUser([
    +      'access administration pages',
    +      'administer inmail',
    +      ]);
    +    $this->drupalLogin($user);
    

    Should go into setup.

  3. +++ b/src/Tests/MultipartMessageHeaderTest.php
    @@ -0,0 +1,225 @@
    +    $regular = drupal_get_path('module', 'inmail_test') . '/eml/multiple-header-fields.eml';
    +    $raw_multipart = file_get_contents(DRUPAL_ROOT . '/' . $regular);
    ...
    +    $processor = \Drupal::service('inmail.processor');
    +    \Drupal::state()->set('inmail.test.success', '');
    +    // Process the raw multipart mail message.
    +    $processor->process('unique_key', $raw_multipart, DelivererConfig::create(['id' => 'test']));
    

    I think we should offer a $this->processMessage($filename).

  4. +++ b/src/Tests/MultipartMessageHeaderTest.php
    @@ -0,0 +1,225 @@
    +    $this->checkOrderOfFields('Received', 'inmail-message__element inmail-message__header__received-date');
    ...
    +  public function checkOrderOfFields($name, $field_class) {
    

    How is this an "Order"?
    Anyway, it's an assert, so the method should start with that.

    This kind of assert is not too common.

  5. +++ b/src/Tests/MultipartMessageHeaderTest.php
    @@ -0,0 +1,225 @@
    +  public function assertNoHeaderField($name) {
    +    $this->assertNoText($name);
    ...
    +  public function assertHeaderField($name, $value) {
    +    $this->assertText($name);
    +    $this->assertText($value);
    

    This is highly ambiguous.
    This is where you want to use xpath.

  6. +++ b/tests/modules/inmail_test/eml/multiple-header-fields.eml
    @@ -0,0 +1,25 @@
    +Subject: I am currently working
    ...
    +Subject: Replica
    

    This header is unexpected for a text/html or text/plain part type.

mbovan’s picture

  1. +++ b/src/Tests/MultipartMessageHeaderTest.php
    @@ -0,0 +1,225 @@
    +class MultipartMessageHeaderTest extends WebTestBase {
    

    There is InmailWebTestBase so we can use that.

    Also, all tests are prefixed with Inmail. Maybe: InmailMultipartMessageWebTest

  2. +++ b/src/Tests/MultipartMessageHeaderTest.php
    @@ -0,0 +1,225 @@
    +    'past',
    

    Not needed in case we have past_db.

  3. +++ b/src/Tests/MultipartMessageHeaderTest.php
    @@ -0,0 +1,225 @@
    +    // Make sure new users are blocked until approved by admin.
    +    \Drupal::configFactory()->getEditable('user.settings')
    +      ->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)
    +      ->save();
    

    Not needed?

  4. +++ b/src/Tests/MultipartMessageHeaderTest.php
    @@ -0,0 +1,225 @@
    +  public function testEmailDisplay() {
    

    This looks like the same method as in IntegrationTest. Let's remove it from there then.

  5. +++ b/src/Tests/MultipartMessageHeaderTest.php
    @@ -0,0 +1,225 @@
    +    $regular = drupal_get_path('module', 'inmail_test') . '/eml/normal.eml';
    +    $raw_multipart = file_get_contents(DRUPAL_ROOT . '/' . $regular);
    ...
    +    $regular = drupal_get_path('module', 'inmail_test') . '/eml/multiple-header-fields.eml';
    +    $raw_multipart = file_get_contents(DRUPAL_ROOT . '/' . $regular);
    

    Now we can use getMessageFileContents() from the base class.

  6. +++ b/src/Tests/MultipartMessageHeaderTest.php
    @@ -0,0 +1,225 @@
    +    $user = $this->drupalCreateUser([
    +      'access administration pages',
    +      'administer inmail',
    +      ]);
    +    $this->drupalLogin($user);
    

    Not sure if this is needed.

  7. +++ b/src/Tests/MultipartMessageHeaderTest.php
    @@ -0,0 +1,225 @@
    +  public function getLastEventByMachinename($machine_name) {
    +    $event_id = db_query_range('SELECT event_id FROM {past_event} WHERE machine_name = :machine_name ORDER BY event_id DESC', 0, 1, [':machine_name' => $machine_name])->fetchField();
    +    if ($event_id) {
    +      return \Drupal::entityManager()
    +        ->getStorage('past_event')
    +        ->load($event_id);
    +    }
    +  }
    

    There is the same method in InmailWebTestBase.

  8. +++ b/src/Tests/MultipartMessageHeaderTest.php
    --- /dev/null
    +++ b/tests/modules/inmail_test/eml/multiple-header-fields.eml
    
    +++ b/tests/modules/inmail_test/eml/multiple-header-fields.eml
    @@ -0,0 +1,25 @@
    +Received: by 10.194.188.75 with HTTP; Tue, 21 Oct 2014 02:21:01 -0700 (PDT)
    +X-Originating-IP: [83.150.36.145]
    +Date: Tue, 21 Oct 2014 11:21:01 +0200
    +Message-ID: <CAFZOsfMjtXehXPGxbiLjydzCY0gCkdngokeQACWQOw+9W5drqQ@mail.gmail.com>
    +Subject: BMH testing sample
    +From: Arild Matsson <arild@masked1.se>
    +To: Arild Matsson <inmail_test@example.com>
    +Cc: Someone Else <inmail_other@example.com>
    

    Is there something new that we are introducing (and testing) in this mail example?

    In case not, it would be perfectly fine to use any other existing mail example (e.g. normal.eml) IMHO.

toncic’s picture

Status: Needs work » Needs review
FileSize
13.73 KB
11.44 KB

Finally I finished the tests and fixed test fails. Now tests doesn't depending of parseAddress issue. Now test pass and should pass when we change parseAdress.

miro_dietiker’s picture

Status: Needs review » Needs work
+++ b/src/Tests/MultipartMessageHeaderTest.php
@@ -0,0 +1,204 @@
+    return $this->assertTrue($exist);
...
+    return $this->assertTrue($exist);

In case of a fail, we need to pass in some meaningful message.

miro_dietiker’s picture

You should/could move the assert helper for that mail Header into a trait. Then it's easy to reuse it in different tests too.

toncic’s picture

Status: Needs work » Needs review
FileSize
19.37 KB
18.52 KB

I created trait AssertHeaderFieldTrait and some function for testing. I creted our function assertContains() because I discussed with @Berdit and we can not use the one witch exist. Patch is not ready yet, just uploading patch to check if I am in right way.

miro_dietiker’s picture

Assigned: toncic » miro_dietiker
Status: Needs review » Needs work

I will look into this again.

tduong’s picture

Status: Needs work » Needs review
FileSize
25.02 KB

I've rerolled and refactored the previous patch since I guess @miro_dietiker doesn't have too much time to fix this.
No interdiff, since it is bigger.
Made some progress providing the assertHelper() methods, but still needs some improvements (like assertElementHeaderField(), "to cover the received-date value" as well). Otherwise it worked pretty fine locally. Didn't tested if these changes affects the other tests though, but we will see if testbot will complain.

Remaining tasks:
- check the @todo's
- and evtl. split the tests that I've marked (// Test 1: ..., // Test 2: ..., ...) into separate test methods

Leave back to whoever wants to work on this. Tomorrow I'll need to work on another project.

Status: Needs review » Needs work

The last submitted patch, 25: write_mail_display-2807733-25.patch, failed testing.

tduong’s picture

Status: Needs work » Needs review
FileSize
38.52 KB

Ok, after more discussion I've provided more asserts methods trying to make it more "loose coupling" as possible:

  • for general address header field, assertAddressHeaderField
  • for address display name, assertAddressDisplayName()
  • for email address, assertEmailAddress()
  • for general header field element (like Date or Subject), assertElementHeaderField()

and started to write an assertUnsubscribeHeaderField() and getHeaderFieldUnsubscribeXpath() but not sure if it is necessary.

Put some @todos, some of them need to be checked now, the other ones can be fixed later as followups (writing the missing tests).

Sorry for taking too long for this "refactoring" issue.

Status: Needs review » Needs work

The last submitted patch, 27: write_mail_display-2807733-27.patch, failed testing.

tduong’s picture

Status: Needs work » Needs review
FileSize
22.78 KB
55.32 KB

Further discussions, reroll and fixing filenames that have been changed during the week.
Currently providing the conversation case as mentioned in #2828497: Create conversation tree mail (see comment #3). Work in progress.

Status: Needs review » Needs work

The last submitted patch, 29: write_mail_display-2807733-29.patch, failed testing.

mbovan’s picture

+++ b/src/Tests/InmailConversationsTest.php
@@ -0,0 +1,63 @@
+class InmailConversationsTest extends InmailWebTestBase {

Since this issue is around for quite some time and the patch is already hard for review (55kB+), I would propose to add InmailConversationsTest either in a followup or actually in #2828497: Create conversation tree mail.

miro_dietiker’s picture

The conversation mail and pseudo-test is clearly a separate issue and hasn't even an overlapping part.

There are private functions in here that could easily be protected.

tduong’s picture

Status: Needs work » Needs review
FileSize
7.85 KB
50.17 KB

Reverted that conversation part. Fixed InmailIntegrationTest.

  • miro_dietiker committed 0940889 on 8.x-1.x authored by tduong
    Issue #2807733 by toncic, tduong, tbonomelli, ModernMantra: Write mail...
miro_dietiker’s picture

Status: Needs review » Fixed

Great work. Committed.

Please create the follow-ups from the @todo mentions.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.