Skip to content

Replaced imap with mailpit and refreshed the test. #13219

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

SakiTakamachi
Copy link
Member

@SakiTakamachi SakiTakamachi commented Jan 22, 2024

take2 of #13197

This uses mailpit

  • TODO: Once the SDKs are merged, change the SDK repository URL back

@SakiTakamachi SakiTakamachi force-pushed the replace_imap_to_mailpit branch 6 times, most recently from 2e9bc34 to 382c355 Compare January 22, 2024 15:39
@SakiTakamachi SakiTakamachi force-pushed the replace_imap_to_mailpit branch from d8e25a3 to 2d94d0f Compare January 22, 2024 16:32
@SakiTakamachi SakiTakamachi marked this pull request as ready for review January 22, 2024 17:03
@SakiTakamachi SakiTakamachi changed the title [WIP] Replaced imap with mailpit and refreshed the test. Replaced imap with mailpit and refreshed the test. Jan 22, 2024
@SakiTakamachi
Copy link
Member Author

@bukka

All comments received in the PR for the mailhog version have been corrected.

@SakiTakamachi
Copy link
Member Author

I don't know if I should specify json as a required extension.

@iluuu1994 iluuu1994 removed their request for review January 22, 2024 17:13
Copy link
Member

@Girgias Girgias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@bukka bukka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good - just some minor comments

}

deleteEmail($res);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it enough to just clear a single email - wouldn't be better to just always clear all emails. That should be also added to CLEAN section in case of failure so nothing is left there.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was honestly confused about this too.

Deleting all emails causes problems with parallel tests, but aren't these tests ever run in parallel?

Also, I was hesitant about the CLEAN section because I would have to use the API several times to delete just one email.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I forgot that unlike mailhog, mailpit can be easily deleted. I can use the CLEAN section.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to other comments, this is data for outgoing emails, so even if there are multiple destinations, there will only be one email.

} else {
echo "Message sent OK\n";
echo "Sent the email.\n";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT:

Suggested change
echo "Sent the email.\n";
echo "Email sent.\n";

and not much point to have else block for this...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right.

$res = searchEmailByToAddress($to);

if (mailCheckResponse($res, $from, $to, $subject, $message)) {
echo "Received the email.\n";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT:

Suggested change
echo "Received the email.\n";
echo "Email received.\n";

just for consistency with email sent ... :)


$bccAddresses = getBccAddresses($res);
if (in_array($bcc, $bccAddresses, true)) {
echo "bcc Received the email.\n";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: This doesn't exactly tests that BCC received the email but more that BCC is set, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Maybe I should test that the email arrived correctly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah and might make sense to do the same for CC. Btw. shouldn't BCC be excluded from the original delivered email?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I was careless.

mailpit (and mailhog) is like an SMTP dummy, so I may not be able to check the behavior on the receiving side.

This test checks "sent mail", not received mail.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah but it's the sender who should send multiple emails. See https://stackoverflow.com/a/2750359 . So I would expect mailpit to have multiple emails received though. Might be worth to try to send BCC email with sendmail to see if it's behaving the same.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but we need to verify that data is sent correctly. In this case it means that multiple RCPT TO are sent which was possible in the previous version. You can see that the client have special handling for BCC in that regard:

php-src/win32/sendmail.c

Lines 525 to 614 in 5da8335

/* Send mail to all Bcc rcpt's
This is basically a rip of the Cc code above.
Just don't forget to remove the Bcc: from the header afterwards. */
if (mailBcc && *mailBcc) {
tempMailTo = estrdup(mailBcc);
/* Send mail to all rcpt's */
token = find_address(tempMailTo, &token_state);
while (token != NULL)
{
SMTP_SKIP_SPACE(token);
FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n");
if ((res = Post(PW32G(mail_buffer))) != SUCCESS) {
efree(tempMailTo);
return (res);
}
if ((res = Ack(&server_response)) != SUCCESS) {
SMTP_ERROR_RESPONSE(server_response);
efree(tempMailTo);
return (res);
}
token = find_address(NULL, &token_state);
}
efree(tempMailTo);
}
else if (headers) {
if ((pos1 = strstr(headers_lc, "bcc:")) && (pos1 == headers_lc || *(pos1-1) == '\n')) {
/* Real offset is memaddress from the original headers + difference of
* string found in the lowercase headers + 4 characters to jump over
* the bcc: */
pos1 = headers + (pos1 - headers_lc) + 4;
if (NULL == (pos2 = strstr(pos1, "\r\n"))) {
tempMailTo = estrndup(pos1, strlen(pos1));
/* Later, when we remove the Bcc: out of the
header we know it was the last thing. */
pos2 = pos1;
} else {
const char *pos3 = pos2;
while (pos2[2] == ' ' || pos2[2] == '\t') {
pos3 = strstr(pos2 + 2, "\r\n");
if (pos3 != NULL) {
pos2 = pos3;
} else {
pos2 += strlen(pos2);
break;
}
}
tempMailTo = estrndup(pos1, pos2 - pos1);
if (pos3 == NULL) {
/* Later, when we remove the Bcc: out of the
header we know it was the last thing. */
pos2 = pos1;
}
}
token = find_address(tempMailTo, &token_state);
while (token != NULL)
{
SMTP_SKIP_SPACE(token);
FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n");
if ((res = Post(PW32G(mail_buffer))) != SUCCESS) {
efree(tempMailTo);
return (res);
}
if ((res = Ack(&server_response)) != SUCCESS) {
SMTP_ERROR_RESPONSE(server_response);
efree(tempMailTo);
return (res);
}
token = find_address(NULL, &token_state);
}
efree(tempMailTo);
/* Now that we've identified that we've a Bcc list,
remove it from the current header. */
stripped_header = ecalloc(1, strlen(headers));
/* headers = point to string start of header
pos1 = pointer IN headers where the Bcc starts
'4' = Length of the characters 'bcc:'
Because we've added +4 above for parsing the Emails
we've to subtract them here. */
memcpy(stripped_header, headers, pos1 - headers - 4);
if (pos1 != pos2) {
/* if pos1 != pos2 , pos2 points to the rest of the headers.
Since pos1 != pos2 if "\r\n" was found, we know those characters
are there and so we jump over them (else we would generate a new header
which would look like "\r\n\r\n". */
memcpy(stripped_header + (pos1 - headers - 4), pos2 + 2, strlen(pos2) - 2);
}
}
}

The client actually strips BCC but seems that mailpit probably adds it back axllent/mailpit@9c8329a

If it's the case, it seems to me that mailpit might be good more for testing the actual email messages rather than making sure that client works as expected. For that it's maybe better to keep the actual real server and possibly just only replace imap client to check it out.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. It's already late today, so I'll try it tomorrow.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have done some checking but only CLI clients seem to be like complete CLI apps (e.g. mutt and alpine) but didn't find anything that would not be probably ideal.

But then I found also this project: https://github.com/nodemailer/wildduck which offers API. I guess it can work just with SMTP mailserver but we already got so maybe that would be a better option. We would basically just replace usage of imap ext with calls to this service that could check the same thing potentially.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you. mailpit is a dummy SMTP server, so I may need something else to actually send.

If we want to test both sending and receiving behavior, things can get a little complicated.

I'll look into it a little more too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In previous tests, the sending/receiving server was the hmail server, and the IMAP extension was acting as an IMAP/POP3 client to the hmail server. wildduck apparently primarily functions as a receiving server, so it needs to be able to receive emails for tests, which can get quite complicated. (In fact, if I look at the documentation, there will be instructions to configure DNS.)

I'll continue investigating.

@SakiTakamachi SakiTakamachi force-pushed the replace_imap_to_mailpit branch from d722de1 to 7039ffa Compare January 23, 2024 12:55
@SakiTakamachi SakiTakamachi deleted the replace_imap_to_mailpit branch February 10, 2024 01:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants