Skip to content

Commit b533c89

Browse files
committed
Tests: Retry apiCheckSubscriberExists
1 parent 040f1d6 commit b533c89

1 file changed

Lines changed: 57 additions & 10 deletions

File tree

tests/Support/Helper/KitAPI.php

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,32 @@ public function apiEncodeState($returnTo, $clientID)
5353
*/
5454
public function apiCheckSubscriberExists($I, $emailAddress, $firstName = false, $customFields = false)
5555
{
56-
// Run request.
57-
$results = $this->apiRequest(
58-
'subscribers',
59-
'GET',
60-
[
61-
'email_address' => $emailAddress,
62-
'include_total_count' => true,
56+
// Wait for the API to update.
57+
$I->wait(3);
6358

64-
// Some test email addresses might bounce, so we want to check all subscriber states.
65-
'status' => 'all',
66-
]
59+
// Retry the API request as sometimes there's a lag before the subscriber is queryable via the API.
60+
$results = $this->retryUntil(
61+
function () use ($emailAddress) {
62+
$results = $this->apiRequest(
63+
'subscribers',
64+
'GET',
65+
[
66+
'email_address' => $emailAddress,
67+
'include_total_count' => true,
68+
69+
// Check all subscriber states.
70+
'status' => 'all',
71+
]
72+
);
73+
74+
// Return the results only if a subscriber was found, so
75+
// retryUntil() will keep trying otherwise.
76+
return ( $results['pagination']['total_count'] > 0 ) ? $results : false;
77+
}
6778
);
6879

6980
// Check at least one subscriber was returned and it matches the email address.
81+
$I->assertNotFalse($results);
7082
$I->assertGreaterThan(0, $results['pagination']['total_count']);
7183
$I->assertEquals($emailAddress, $results['subscribers'][0]['email_address']);
7284

@@ -288,4 +300,39 @@ public function apiRequest($endpoint, $method = 'GET', $params = array())
288300
// Return JSON decoded response.
289301
return json_decode($result->getBody()->getContents(), true);
290302
}
303+
304+
/**
305+
* Repeatedly invokes the given callback until it returns a truthy value, or
306+
* the maximum number of attempts is reached.
307+
*
308+
* Use this to wrap API checks that can be flaky due to ingestion lag at
309+
* Kit's end (e.g. a subscriber created via a form submission isn't always
310+
* immediately queryable via the `subscribers` endpoint).
311+
*
312+
* @since 1.9.4
313+
*
314+
* @param callable $callback Callback to invoke. Should return the value
315+
* to use, or false/null to indicate the
316+
* check has not yet succeeded.
317+
* @param int $attempts Maximum number of attempts.
318+
* @param int $delay Seconds to wait between attempts.
319+
* @return mixed The truthy value returned by $callback, or
320+
* false if all attempts are exhausted.
321+
*/
322+
private function retryUntil(callable $callback, $attempts = 4, $delay = 3)
323+
{
324+
for ($i = 0; $i < $attempts; $i++) {
325+
$result = $callback();
326+
if ($result) {
327+
return $result;
328+
}
329+
330+
// Don't sleep after the final attempt.
331+
if ($i < $attempts - 1) {
332+
sleep($delay);
333+
}
334+
}
335+
336+
return false;
337+
}
291338
}

0 commit comments

Comments
 (0)