Skip to content

Commit

Permalink
Fixes unstable email integration tests, by asserting the content usin…
Browse files Browse the repository at this point in the history
…g DomNodes.
  • Loading branch information
hostep committed Apr 19, 2020
1 parent c163118 commit 69fcf67
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace Magento\Newsletter\Model;

use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Framework\Mail\EmailMessage;
use Magento\Framework\ObjectManagerInterface;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\Mail\Template\TransportBuilderMock;
Expand Down Expand Up @@ -55,10 +56,11 @@ public function testEmailConfirmation(): void
$subscriber = $this->subscriberFactory->create();
$subscriber->subscribe('[email protected]');
// confirmationCode 'ysayquyajua23iq29gxwu2eax2qb6gvy' is taken from fixture
$this->assertContains(
$this->assertEmailContains(
'/newsletter/subscriber/confirm/id/' . $subscriber->getSubscriberId()
. '/code/ysayquyajua23iq29gxwu2eax2qb6gvy',
$this->transportBuilder->getSentMessage()->getBody()->getParts()[0]->getRawContent()
'//p/a/@href',
$this->transportBuilder->getSentMessage()
);
$this->assertEquals(Subscriber::STATUS_NOT_ACTIVE, $subscriber->getSubscriberStatus());
}
Expand Down Expand Up @@ -87,17 +89,19 @@ public function testUnsubscribeSubscribe(): void
$subscriber = $this->subscriberFactory->create();
$this->assertSame($subscriber, $subscriber->loadByCustomerId(1));
$this->assertEquals($subscriber, $subscriber->unsubscribe());
$this->assertContains(
$this->assertEmailContains(
'You have been unsubscribed from the newsletter.',
$this->transportBuilder->getSentMessage()->getRawMessage()
'//td[@class="main-content"]',
$this->transportBuilder->getSentMessage()
);
$this->assertEquals(Subscriber::STATUS_UNSUBSCRIBED, $subscriber->getSubscriberStatus());
// Subscribe and verify
$this->assertEquals(Subscriber::STATUS_SUBSCRIBED, $subscriber->subscribe('[email protected]'));
$this->assertEquals(Subscriber::STATUS_SUBSCRIBED, $subscriber->getSubscriberStatus());
$this->assertContains(
$this->assertEmailContains(
'You have been successfully subscribed to our newsletter.',
$this->transportBuilder->getSentMessage()->getRawMessage()
'//td[@class="main-content"]',
$this->transportBuilder->getSentMessage()
);
}

Expand All @@ -114,16 +118,18 @@ public function testUnsubscribeSubscribeByCustomerId(): void
// Unsubscribe and verify
$this->assertSame($subscriber, $subscriber->unsubscribeCustomerById(1));
$this->assertEquals(Subscriber::STATUS_UNSUBSCRIBED, $subscriber->getSubscriberStatus());
$this->assertContains(
$this->assertEmailContains(
'You have been unsubscribed from the newsletter.',
$this->transportBuilder->getSentMessage()->getRawMessage()
'//td[@class="main-content"]',
$this->transportBuilder->getSentMessage()
);
// Subscribe and verify
$this->assertSame($subscriber, $subscriber->subscribeCustomerById(1));
$this->assertEquals(Subscriber::STATUS_SUBSCRIBED, $subscriber->getSubscriberStatus());
$this->assertContains(
$this->assertEmailContains(
'You have been successfully subscribed to our newsletter.',
$this->transportBuilder->getSentMessage()->getRawMessage()
'//td[@class="main-content"]',
$this->transportBuilder->getSentMessage()
);
}

Expand All @@ -141,9 +147,10 @@ public function testConfirm(): void
$subscriber->subscribe($customerEmail);
$subscriber->loadByEmail($customerEmail);
$subscriber->confirm($subscriber->getSubscriberConfirmCode());
$this->assertContains(
$this->assertEmailContains(
'You have been successfully subscribed to our newsletter.',
$this->transportBuilder->getSentMessage()->getRawMessage()
'//td[@class="main-content"]',
$this->transportBuilder->getSentMessage()
);
}

Expand Down Expand Up @@ -174,4 +181,37 @@ public function testSubscribeUnconfirmedCustomerWithoutSubscription(): void
$subscriber->subscribeCustomerById($customer->getId());
$this->assertEquals(Subscriber::STATUS_UNCONFIRMED, $subscriber->getStatus());
}

/**
* Verifies if certain content is contained in the provided xpath in the email template
* The xpath provided can only match a single node!
*
* @param string $expectedGreeting
* @param string $xpath
* @param EmailMessage $message
*/
private function assertEmailContains(string $expected, string $xpath, EmailMessage $message)
{
$messageContent = $this->getMessageRawContent($message);
$emailDom = new \DOMDocument();
$emailDom->loadHTML($messageContent);

$emailXpath = new \DOMXPath($emailDom);
$emailDomNodes = $emailXpath->query($xpath);

$this->assertSame(1, $emailDomNodes->length);
$this->assertContains($expected, $emailDomNodes->item(0)->textContent);
}

/**
* Returns raw content of provided message
*
* @param EmailMessage $message
* @return string
*/
private function getMessageRawContent(EmailMessage $message): string
{
$emailParts = $message->getBody()->getParts();
return current($emailParts)->getRawContent();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Framework\Mail\EmailMessage;
use Magento\ProductAlert\Model\Email;
use Magento\Store\Model\Website;
use Magento\TestFramework\Mail\Template\TransportBuilderMock;
Expand Down Expand Up @@ -100,9 +101,10 @@ public function testSend($isCustomerIdUsed)
$this->_emailModel->addPriceProduct($product);
$this->_emailModel->send();

$this->assertContains(
'Smith,',
$this->transportBuilder->getSentMessage()->getRawMessage()
$this->assertEmailContains(
'John Smith,',
'//p[@class="greeting"]',
$this->transportBuilder->getSentMessage()
);
}

Expand Down Expand Up @@ -146,14 +148,49 @@ public function testEmailForDifferentCustomers(): void
$this->_emailModel->setType('stock');
$this->_emailModel->send();

$expectedPriceBox = '<span id="product-price-' . $product->getId() . '" data-price-amount="'
. $expectedPrice . '" data-price-type="finalPrice" '
. 'class="price-wrapper "><span class="price">$' . $expectedPrice . '.00</span></span>';

$this->assertContains(
$expectedPriceBox,
$this->transportBuilder->getSentMessage()->getBody()->getParts()[0]->getRawContent()
$this->assertEmailContains(
$expectedPrice,
'//span[@id="product-price-' . $product->getId() . '"]/@data-price-amount',
$this->transportBuilder->getSentMessage()
);
$this->assertEmailContains(
'$' . $expectedPrice . '.00',
'//span[@id="product-price-' . $product->getId() . '"]/span[@class="price"]',
$this->transportBuilder->getSentMessage()
);
}
}

/**
* Verifies if certain content is contained in the provided xpath in the email template
* The xpath provided can only match a single node!
*
* @param string $expectedGreeting
* @param string $xpath
* @param EmailMessage $message
*/
private function assertEmailContains(string $expected, string $xpath, EmailMessage $message)
{
$messageContent = $this->getMessageRawContent($message);
$emailDom = new \DOMDocument();
$emailDom->loadHTML($messageContent);

$emailXpath = new \DOMXPath($emailDom);
$emailDomNodes = $emailXpath->query($xpath);

$this->assertSame(1, $emailDomNodes->length);
$this->assertContains($expected, $emailDomNodes->item(0)->textContent);
}

/**
* Returns raw content of provided message
*
* @param EmailMessage $message
* @return string
*/
private function getMessageRawContent(EmailMessage $message): string
{
$emailParts = $message->getBody()->getParts();
return current($emailParts)->getRawContent();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Magento\Customer\Model\Session;
use Magento\Framework\App\Area;
use Magento\Framework\Locale\Resolver;
use Magento\Framework\Mail\EmailMessage;
use Magento\Framework\Module\Dir\Reader;
use Magento\Framework\Phrase;
use Magento\Framework\Phrase\Renderer\Translate as PhraseRendererTranslate;
Expand Down Expand Up @@ -69,9 +70,10 @@ public function setUp()
public function testProcess()
{
$this->observer->process();
$this->assertContains(
'ohn Smith,',
$this->transportBuilder->getSentMessage()->getRawMessage()
$this->assertEmailContains(
'John Smith,',
'//p[@class="greeting"]',
$this->transportBuilder->getSentMessage()
);
}

Expand Down Expand Up @@ -120,7 +122,48 @@ public function testProcessPortuguese()
$message = $this->transportBuilder->getSentMessage();
$messageContent = $message->getBody()->getParts()[0]->getRawContent();
$expectedText = array_shift($translation);
$this->assertContains('/frontend/Magento/luma/pt_BR/', $messageContent);
$this->assertContains(substr($expectedText, 0, 50), $messageContent);
$this->assertEmailContains(
'/frontend/Magento/luma/pt_BR/',
'//span[@class="product-image-wrapper"]/img/@src',
$this->transportBuilder->getSentMessage()
);
$this->assertEmailContains(
$expectedText,
'//p[@class="greeting"]/following-sibling::p[1]',
$this->transportBuilder->getSentMessage()
);
}

/**
* Verifies if certain content is contained in the provided xpath in the email template
* The xpath provided can only match a single node!
*
* @param string $expectedGreeting
* @param string $xpath
* @param EmailMessage $message
*/
private function assertEmailContains(string $expected, string $xpath, EmailMessage $message)
{
$messageContent = $this->getMessageRawContent($message);
$emailDom = new \DOMDocument();
$emailDom->loadHTML($messageContent);

$emailXpath = new \DOMXPath($emailDom);
$emailDomNodes = $emailXpath->query($xpath);

$this->assertSame(1, $emailDomNodes->length);
$this->assertContains($expected, $emailDomNodes->item(0)->textContent);
}

/**
* Returns raw content of provided message
*
* @param EmailMessage $message
* @return string
*/
private function getMessageRawContent(EmailMessage $message): string
{
$emailParts = $message->getBody()->getParts();
return current($emailParts)->getRawContent();
}
}

0 comments on commit 69fcf67

Please sign in to comment.