Add member index
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
62b0486f89
commit
c4c59d1d28
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mailman\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class MailmanServiceException extends Exception
|
||||
{
|
||||
}
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
namespace App\Mailman\Support;
|
||||
|
||||
use App\Mailman\Exceptions\MailmanServiceException;
|
||||
use Illuminate\Http\Client\PendingRequest;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\LazyCollection;
|
||||
|
||||
class MailmanService
|
||||
{
|
||||
|
@ -27,6 +29,31 @@ class MailmanService
|
|||
return 200 === $response->status();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LazyCollection<int, string>
|
||||
*/
|
||||
public function members(string $listId): LazyCollection
|
||||
{
|
||||
$page = 1;
|
||||
|
||||
return LazyCollection::make(function () use ($listId, $page) {
|
||||
while (!isset($totalEntries) || ($page - 1) * 10 + 1 <= $totalEntries) {
|
||||
$response = $this->http()->get('/lists/'.$listId.'/roster/member?page='.$page.'&count=10');
|
||||
throw_unless($response->ok(), MailmanServiceException::class, 'Fetching members for listId '.$listId.' failed.');
|
||||
/** @var array<int, array{email: string}>|null */
|
||||
$entries = data_get($response->json(), 'entries');
|
||||
throw_if(is_null($entries), MailmanServiceException::class, 'Failed getting member list from response');
|
||||
$totalEntries = data_get($response->json(), 'total_size');
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
yield $entry['email'];
|
||||
}
|
||||
|
||||
++$page;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private function http(): PendingRequest
|
||||
{
|
||||
return Http::withBasicAuth($this->username, $this->password)->withOptions(['base_uri' => $this->baseUrl]);
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
namespace Tests\Unit\Mailman;
|
||||
|
||||
use App\Mailman\Exceptions\MailmanServiceException;
|
||||
use App\Mailman\Support\MailmanService;
|
||||
use Generator;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Tests\TestCase;
|
||||
|
||||
|
@ -35,4 +37,65 @@ class ServiceTest extends TestCase
|
|||
Http::assertSentCount(1);
|
||||
Http::assertSent(fn ($request) => 'GET' === $request->method() && 'http://mailman.test/api/system/versions' === $request->url() && $request->header('Authorization') === ['Basic '.base64_encode('user:secret')]);
|
||||
}
|
||||
|
||||
public function testItGetsMembersFromList(): void
|
||||
{
|
||||
Http::fake([
|
||||
'http://mailman.test/api/lists/listid/roster/member?page=1&count=10' => Http::response(json_encode([
|
||||
'entries' => [
|
||||
['email' => 'test@example.com'],
|
||||
['email' => 'test2@example.com'],
|
||||
],
|
||||
'total_size' => 2,
|
||||
]), 200),
|
||||
]);
|
||||
|
||||
$result = app(MailmanService::class)->setCredentials('http://mailman.test/api/', 'user', 'secret')->members('listid');
|
||||
|
||||
$this->assertEquals(['test@example.com', 'test2@example.com'], $result->toArray());
|
||||
Http::assertSentCount(1);
|
||||
Http::assertSent(fn ($request) => 'GET' === $request->method() && 'http://mailman.test/api/lists/listid/roster/member?page=1&count=10' === $request->url() && $request->header('Authorization') === ['Basic '.base64_encode('user:secret')]);
|
||||
}
|
||||
|
||||
public function testItThrowsExceptionWhenLoginFailed(): void
|
||||
{
|
||||
$this->expectException(MailmanServiceException::class);
|
||||
Http::fake([
|
||||
'http://mailman.test/api/lists/listid/roster/member?page=1&count=10' => Http::response('', 401),
|
||||
]);
|
||||
|
||||
app(MailmanService::class)->setCredentials('http://mailman.test/api/', 'user', 'secret')->members('listid')->first();
|
||||
}
|
||||
|
||||
public function listDataProvider(): Generator
|
||||
{
|
||||
foreach (range(3, 40) as $i) {
|
||||
yield [
|
||||
collect(range(1, $i))
|
||||
->map(fn ($num) => ['email' => 'test'.$num.'@example.com'])
|
||||
->toArray(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider listDataProvider
|
||||
*/
|
||||
public function testItReturnsMoreThanOneResult(array $totals): void
|
||||
{
|
||||
$totals = collect($totals);
|
||||
foreach ($totals->chunk(10) as $n => $chunk) {
|
||||
Http::fake([
|
||||
'http://mailman.test/api/lists/listid/roster/member?page='.($n + 1).'&count=10' => Http::response(json_encode([
|
||||
'entries' => $chunk,
|
||||
'total_size' => $totals->count(),
|
||||
]), 200),
|
||||
]);
|
||||
}
|
||||
|
||||
$result = app(MailmanService::class)->setCredentials('http://mailman.test/api/', 'user', 'secret')->members('listid');
|
||||
|
||||
$this->assertCount($totals->count(), $result->toArray());
|
||||
Http::assertSentCount($totals->chunk(10)->count());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue