Skip to content
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

(REF) MockPublicFormTest - Small cleanups/fixups #31147

Closed
wants to merge 4 commits into from
Closed
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
2 changes: 1 addition & 1 deletion CRM/Utils/GuzzleMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ public static function curlLog(\Psr\Log\LoggerInterface $logger) {

$curlFmt = new class() extends \GuzzleHttp\MessageFormatter {

public function format(RequestInterface $request, ResponseInterface $response = NULL, \Exception $error = NULL) {
public function format(RequestInterface $request, ?ResponseInterface $response = NULL, ?\Throwable $error = NULL): string {
$cmd = '$ curl';
if ($request->getMethod() !== 'GET') {
$cmd .= ' -X ' . escapeshellarg($request->getMethod());
Expand Down
115 changes: 53 additions & 62 deletions ext/afform/mock/tests/phpunit/E2E/AfformMock/MockPublicFormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,80 +67,50 @@ public function testPublicEditDisallowed() {
}

/**
* The email token `{afform.mockPublicFormUrl}` should evaluate to an authenticated URL.
* There are two tokens ({afform.mockPublicFormUrl} and {afform.mockPublicFormLink})
* which are rendered in two contexts (text and HTML).
*
* Make sure that the resulting URLs point to the same place, regardless of which
* variant or environment is used.
*
* @return void
*/
public function testAuthenticatedUrlToken_Plain() {
if (!function_exists('authx_civicrm_config')) {
$this->fail('Cannot test without authx');
}

public function testWellFormedTokens() {
$lebowski = $this->getLebowskiCID();
$text = $this->renderTokens($lebowski, 'Please go to {afform.mockPublicFormUrl}', 'text/plain');
if (!preg_match(';Please go to ([^\s]+);', $text, $m)) {
$this->fail('Plain text message did not have URL in expected place: ' . $text);
}
$url = $m[1];
$this->assertMatchesRegularExpression(';^https?:.*civicrm/mock-public-form.*;', $url, "URL should look plausible");
$messages = \CRM_Core_TokenSmarty::render([
'text' => 'url=({afform.mockPublicFormUrl}) link=({afform.mockPublicFormLink})',
'html' => '<p>url=({afform.mockPublicFormUrl}) link=({afform.mockPublicFormLink})</p>',
], ['contactId' => $lebowski]);

// Going to this page will cause us to authenticate as the target contact
$http = $this->createGuzzle(['http_errors' => FALSE, 'cookies' => new \GuzzleHttp\Cookie\CookieJar()]);
$response = $http->get($url);
$r = (string) $response->getBody();
$this->assertStatusCode(200, $response);
$response = $http->get('civicrm/authx/id');
$this->assertContactJson($lebowski, $response);
}
$httpTextUrl = '(https?:[a-zA-Z0-9_/\.\?\-\+:=#&]+)';
$httpHtmlUrl = '(https?:[a-zA-Z0-9_/\.\?\-\+:=#&\;]+)';
$textPattern = ";url=\($httpTextUrl\) link=\(\[My public form\]\($httpTextUrl\)\); ";
$htmlPattern = ";\<p\>url=\($httpHtmlUrl\) link=\(<a href=\"$httpHtmlUrl\">My public form</a>\)\</p\>;";

/**
* The email token `{afform.mockPublicFormUrl}` should evaluate to an authenticated URL.
*/
public function testAuthenticatedUrlToken_Html() {
if (!function_exists('authx_civicrm_config')) {
$this->fail('Cannot test without authx');
}
$this->assertMatchesRegularExpression($textPattern, $messages['text']);
$this->assertMatchesRegularExpression($htmlPattern, $messages['html']);

$lebowski = $this->getLebowskiCID();
$html = $this->renderTokens($lebowski, 'Please go to <a href="{afform.mockPublicFormUrl}">my form</a>', 'text/html');
preg_match($textPattern, $messages['text'], $textMatches);
preg_match($htmlPattern, $messages['html'], $htmlMatches);

if (!preg_match(';a href="([^"]+)";', $html, $m)) {
$this->fail('HTML message did not have URL in expected place: ' . $html);
}
$url = html_entity_decode($m[1]);
$this->assertMatchesRegularExpression(';^https?:.*civicrm/mock-public-form.*;', $url, "URL should look plausible");
$this->assertEquals($textMatches[1], html_entity_decode($htmlMatches[1]), 'Text and HTML values of {afform.mockPublicFormUrl} should point to same place');
$this->assertEquals($textMatches[2], html_entity_decode($htmlMatches[2]), 'Text and HTML values of {afform.mockPublicFormLink} should point to same place');

// Going to this page will cause us to authenticate as the target contact
$http = $this->createGuzzle(['cookies' => new \GuzzleHttp\Cookie\CookieJar()]);
$response = $http->get($url);
$this->assertStatusCode(200, $response);
$response = $http->get('civicrm/authx/id');
$this->assertContactJson($lebowski, $response);
$this->assertMatchesRegularExpression(';^https?:.*civicrm/mock-public-form.*;', $textMatches[1], "URL should look plausible");
$this->assertMatchesRegularExpression(';^https?:.*civicrm/mock-public-form.*;', $textMatches[2], "URL should look plausible");
}

/**
* The email token `{afform.mockPublicFormLink}` should evaluate to an authenticated URL.
* The email token `{afform.mockPublicFormUrl}` should evaluate to an authenticated URL.
*/
public function testAuthenticatedLinkToken_Html() {
if (!function_exists('authx_civicrm_config')) {
$this->fail('Cannot test without authx');
}
public function testAuthenticatedUrlToken() {
$this->assertTrue(function_exists('authx_civicrm_config'), 'Cannot test without authx');

$lebowski = $this->getLebowskiCID();
$html = $this->renderTokens($lebowski, 'Please go to {afform.mockPublicFormLink}', 'text/html');
$doc = \phpQuery::newDocument($html, 'text/html');
$this->assertEquals(1, $doc->find('a')->count(), 'Document should have hyperlink');
foreach ($doc->find('a') as $item) {
/** @var \DOMElement $item */
$this->assertMatchesRegularExpression(';^https?:.*civicrm/mock-public-form.*;', $item->getAttribute('href'));
$this->assertEquals('My public form', $item->firstChild->data);
$url = $item->getAttribute('href');
}

// Going to this page will cause us to authenticate as the target contact
$http = $this->createGuzzle(['cookies' => new \GuzzleHttp\Cookie\CookieJar()]);
$response = $http->get($url);
$this->assertStatusCode(200, $response);
$response = $http->get('civicrm/authx/id');
$this->assertContactJson($lebowski, $response);
$url = $this->renderTokens($lebowski, '{afform.mockPublicFormUrl}', 'text/plain');
$this->assertMatchesRegularExpression(';^https?:.*civicrm/mock-public-form.*;', $url, "URL should look plausible");

$this->assertUrlStartsSession($url, $lebowski);
}

protected function renderTokens($cid, $body, $format) {
Expand All @@ -151,7 +121,7 @@ protected function renderTokens($cid, $body, $format) {
return $tp->getRow(0)->render('example');
}

protected function getLebowskiCID() {
protected function getLebowskiCID(): int {
$contact = \civicrm_api3('Contact', 'create', [
'contact_type' => 'Individual',
'first_name' => 'Jeffrey',
Expand Down Expand Up @@ -179,4 +149,25 @@ public function assertContactJson($cid, $response) {
$this->assertEquals($cid, $j['contact_id'], "Response did not give expected contact ID\n" . $formattedFailure);
}

/**
* Opening $url
*
* @param string $url
* @param int $contactId
*
* @return void
* @throws \GuzzleHttp\Exception\GuzzleException
*/
protected function assertUrlStartsSession(string $url, int $contactId): void {
$http = $this->createGuzzle([
'http_errors' => FALSE,
'cookies' => new \GuzzleHttp\Cookie\CookieJar(),
]);
$response = $http->get($url);
$r = (string) $response->getBody();
$this->assertStatusCode(200, $response);
$response = $http->get('civicrm/authx/id');
$this->assertContactJson($contactId, $response);
}

}