Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 21 additions & 32 deletions tests/acceptance/TestHelpers/EmailHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,10 @@ public static function getBodyOfAnEmailById(
}

/**
* Returns the body of the last received email for the provided receiver according to the provided email address and the serial number
* For email number, 1 means the latest one
* Returns the body of the last received email for the provided receiver
*
* @param string $emailAddress
* @param string|null $xRequestId
* @param int|null $emailNumber For email number, 1 means the latest one
* @param int|null $waitTimeSec Time to wait for the email if the email has been delivered
* @param string $xRequestId
*
* @return string
* @throws GuzzleException
Expand All @@ -142,48 +139,40 @@ public static function getBodyOfAnEmailById(
public static function getBodyOfLastEmail(
string $emailAddress,
string $xRequestId,
?int $emailNumber = 1,
?int $waitTimeSec = EMAIL_WAIT_TIMEOUT_SEC
): string {
$currentTime = \time();
$endTime = $currentTime + $waitTimeSec;
$mailBox = self::getMailBoxFromEmail($emailAddress);
while ($currentTime <= $endTime) {
$mailboxResponse = self::getMailboxInformation($mailBox, $xRequestId);
if (!empty($mailboxResponse) && \sizeof($mailboxResponse) >= $emailNumber) {
$mailboxId = $mailboxResponse[\sizeof($mailboxResponse) - $emailNumber]->id;
$response = self::getBodyOfAnEmailById($mailBox, $mailboxId, $xRequestId);
$body = \str_replace(
"\r\n",
"\n",
\quoted_printable_decode($response->body->text . "\n" . $response->body->html)
);
return $body;
}
\usleep(STANDARD_SLEEP_TIME_MICROSEC * 50);
$currentTime = \time();
$emails = self::getMailboxInformation($mailBox, $xRequestId);
if (!empty($emails)) {
$emailId = \array_pop($emails)->id;
$response = self::getBodyOfAnEmailById($mailBox, $emailId, $xRequestId);
$body = \str_replace(
"\r\n",
"\n",
\quoted_printable_decode($response->body->text . "\n" . $response->body->html)
);
return $body;
}
throw new Exception("Could not find the email to the address: " . $emailAddress);
return "";
}

/**
* Deletes all the emails for the provided mailbox
*
* @param string $localInbucketUrl
* @param string|null $xRequestId
* @param string $url
* @param string $mailBox
* @param string $xRequestId
*
* @return ResponseInterface
* @throws GuzzleException
*/
public static function deleteAllEmailsForAMailbox(
string $localInbucketUrl,
?string $xRequestId,
string $mailBox
public static function deleteAllEmails(
string $url,
string $mailBox,
string $xRequestId,
): ResponseInterface {
return HttpRequestHelper::delete(
$localInbucketUrl . "/api/v1/mailbox/" . $mailBox,
$xRequestId
$url . "/api/v1/mailbox/" . $mailBox,
$xRequestId,
);
}
}
4 changes: 2 additions & 2 deletions tests/acceptance/TestHelpers/HttpRequestHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class HttpRequestHelper {
public static function numRetriesOnHttpTooEarly(): int {
// Currently reva and OpenCloud may return HTTP_TOO_EARLY
// So try up to 10 times before giving up.
return 10;
return STANDARD_RETRY_COUNT;
}

/**
Expand Down Expand Up @@ -732,7 +732,7 @@ public static function parseResponseAsXml(ResponseInterface $response): array {
*/
public static function getRequestTimeout(): int {
$timeout = \getenv("REQUEST_TIMEOUT");
return (int)$timeout ?: 60;
return (int)$timeout ?: HTTP_REQUEST_TIMEOUT;
}

/**
Expand Down
64 changes: 48 additions & 16 deletions tests/acceptance/bootstrap/NotificationContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -589,36 +589,68 @@ public function assertEmailContains(
): void {
$address = $this->featureContext->getEmailAddressForUser($user);
$this->featureContext->pushEmailRecipientAsMailBox($address);
$actualEmailBodyContent = EmailHelper::getBodyOfLastEmail($address, $this->featureContext->getStepLineRef());
if ($ignoreWhiteSpace) {
$expectedEmailBodyContent = preg_replace('/\s+/', '', $expectedEmailBodyContent);
$actualEmailBodyContent = preg_replace('/\s+/', '', $actualEmailBodyContent);
}

// assert with retries as email delivery might be delayed
$retried = 0;
do {
$actualEmailBodyContent = EmailHelper::getBodyOfLastEmail(
$address,
$this->featureContext->getStepLineRef()
);
if ($ignoreWhiteSpace) {
$expectedEmailBodyContent = preg_replace('/\s+/', '', $expectedEmailBodyContent);
$actualEmailBodyContent = preg_replace('/\s+/', '', $actualEmailBodyContent);
}
$tryAgain = !\str_contains($actualEmailBodyContent, $expectedEmailBodyContent)
&& $retried <= STANDARD_RETRY_COUNT;
$retried++;
if ($tryAgain) {
$mailBox = EmailHelper::getMailBoxFromEmail($address);
echo "[INFO] Checking last email content for '$mailBox'. (Retry $retried)\n";
// wait for 1 second before trying again
sleep(1);
}
} while ($tryAgain);
Assert::assertStringContainsString(
$expectedEmailBodyContent,
$actualEmailBodyContent,
"The email address '$address' should have received an"
. "email with the body containing $expectedEmailBodyContent
but the received email is $actualEmailBodyContent"
. " email with the body containing '$expectedEmailBodyContent'"
. " but the received email is '$actualEmailBodyContent'"
);
}

/**
* Delete all the inbucket emails
* Delete all emails from the mailboxes
*
* @AfterScenario @email
*
* @return void
*/
public function clearInbucketMessages(): void {
public function clearMailboxes(): void {
$users = \array_keys($this->featureContext->getCreatedUsers());
try {
if (!empty($this->featureContext->emailRecipients)) {
foreach ($this->featureContext->emailRecipients as $emailRecipient) {
EmailHelper::deleteAllEmailsForAMailbox(
EmailHelper::getLocalEmailUrl(),
$this->featureContext->getStepLineRef(),
$emailRecipient
);
if (!empty($users)) {
foreach ($users as $emailRecipient) {
$retried = 0;
do {
$res = EmailHelper::deleteAllEmails(
EmailHelper::getLocalEmailUrl(),
$emailRecipient,
$this->featureContext->getStepLineRef(),
);
$deleteStatus = $res->getStatusCode();
$mailBox = EmailHelper::getMailboxInformation($emailRecipient);
$tryAgain = ($deleteStatus !== 200 || !empty($mailBox)) && $retried <= STANDARD_RETRY_COUNT;
$retried++;
if ($tryAgain) {
echo "[INFO] Clearing mailbox '$emailRecipient'."
. " Status: $deleteStatus. Emails: " . \count($mailBox) . "."
. " (Retry $retried)\n";
// wait for 1 second before trying again
sleep(1);
}
} while ($tryAgain);
}
}
} catch (Exception $e) {
Expand Down
43 changes: 6 additions & 37 deletions tests/acceptance/bootstrap/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,51 +27,20 @@

$classLoader->register();

// Sleep for 10 milliseconds
if (!\defined('STANDARD_SLEEP_TIME_MILLISEC')) {
\define('STANDARD_SLEEP_TIME_MILLISEC', 10);
}

if (!\defined('STANDARD_SLEEP_TIME_MICROSEC')) {
\define('STANDARD_SLEEP_TIME_MICROSEC', STANDARD_SLEEP_TIME_MILLISEC * 1000);
}

// Long timeout for use in code that needs to wait for known slow UI
if (!\defined('LONG_UI_WAIT_TIMEOUT_MILLISEC')) {
\define('LONG_UI_WAIT_TIMEOUT_MILLISEC', 60000);
}

// Default timeout for use in code that needs to wait for the UI
if (!\defined('STANDARD_UI_WAIT_TIMEOUT_MILLISEC')) {
\define('STANDARD_UI_WAIT_TIMEOUT_MILLISEC', 10000);
}

// Minimum timeout for use in code that needs to wait for the UI
if (!\defined('MINIMUM_UI_WAIT_TIMEOUT_MILLISEC')) {
\define('MINIMUM_UI_WAIT_TIMEOUT_MILLISEC', 500);
}

if (!\defined('MINIMUM_UI_WAIT_TIMEOUT_MICROSEC')) {
\define('MINIMUM_UI_WAIT_TIMEOUT_MICROSEC', MINIMUM_UI_WAIT_TIMEOUT_MILLISEC * 1000);
}

// Minimum timeout for emails
if (!\defined('EMAIL_WAIT_TIMEOUT_SEC')) {
\define('EMAIL_WAIT_TIMEOUT_SEC', 10);
}
if (!\defined('EMAIL_WAIT_TIMEOUT_MILLISEC')) {
\define('EMAIL_WAIT_TIMEOUT_MILLISEC', EMAIL_WAIT_TIMEOUT_SEC * 1000);
}

// Default number of times to retry where retries are useful
if (!\defined('STANDARD_RETRY_COUNT')) {
\define('STANDARD_RETRY_COUNT', 5);
\define('STANDARD_RETRY_COUNT', 10);
}
// Minimum number of times to retry where retries are useful
if (!\defined('MINIMUM_RETRY_COUNT')) {
\define('MINIMUM_RETRY_COUNT', 2);
}

// Minimum number of times to retry where retries are useful
if (!\defined('HTTP_REQUEST_TIMEOUT')) {
\define('HTTP_REQUEST_TIMEOUT', 60);
}

// The remote server-under-test might or might not happen to have this directory.
// If it does not exist, then the tests may end up creating it.
if (!\defined('ACCEPTANCE_TEST_DIR_ON_REMOTE_SERVER')) {
Expand Down