refactor: use bus batch in davclient (#5542)

This commit is contained in:
Alexis Saettler
2021-10-03 19:00:57 +02:00
committed by GitHub
parent e8ca11ad09
commit 8394386345
32 changed files with 1219 additions and 396 deletions
+1 -1
View File
@@ -359,7 +359,7 @@ class DavTester extends TestCase
"</card:addressbook-multiget>\n", 'REPORT');
}
public function multistatusHeader()
public static function multistatusHeader()
{
return '<d:multistatus xmlns:d="DAV:" xmlns:card="urn:ietf:params:xml:ns:carddav">';
}
+16
View File
@@ -44,6 +44,22 @@ abstract class TestCase extends BaseTestCase
$property->setValue($object, $value);
}
/**
* Get protected/private property of a class.
*
* @param object &$object
* @param string $propertyName
* @return mixed
*/
public function getPrivateValue(&$object, string $propertyName)
{
$reflection = new \ReflectionClass(get_class($object));
$property = $reflection->getProperty($propertyName);
$property->setAccessible(true);
return $property->getValue($object);
}
/**
* Test that the response contains an ObjectDeleted response.
*
@@ -0,0 +1,172 @@
<?php
namespace Tests\Unit\Jobs\Dav;
use Tests\TestCase;
use App\Models\User\User;
use Mockery\MockInterface;
use Tests\Api\DAV\CardEtag;
use App\Jobs\Dav\UpdateVCard;
use App\Models\Contact\Contact;
use Illuminate\Bus\PendingBatch;
use App\Jobs\Dav\GetMultipleVCard;
use Illuminate\Support\Facades\Bus;
use Sabre\CardDAV\Plugin as CardDAVPlugin;
use Illuminate\Bus\DatabaseBatchRepository;
use App\Models\Account\AddressBookSubscription;
use App\Services\DavClient\Utils\Dav\DavClient;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class GetMultipleVCardTest extends TestCase
{
use DatabaseTransactions;
use CardEtag;
/** @test */
public function it_get_cards()
{
$fake = Bus::fake();
$user = factory(User::class)->create();
$addressBookSubscription = AddressBookSubscription::factory()->create([
'account_id' => $user->account_id,
'user_id' => $user->id,
]);
$contact = new Contact();
$contact->forceFill([
'first_name' => 'Test',
'uuid' => 'affacde9-b2fe-4371-9acb-6612aaee6971',
'updated_at' => now(),
]);
$card = $this->getCard($contact);
$etag = $this->getEtag($contact, true);
$this->mock(DavClient::class, function (MockInterface $mock) use ($card, $etag) {
$mock->shouldReceive('addressbookMultiget')
->once()
->withArgs(function ($request, $properties, $contacts) {
$this->assertEquals([
'{DAV:}getetag',
[
'name' => '{'.CardDAVPlugin::NS_CARDDAV.'}address-data',
'value' => null,
'attributes' => [
'content-type' => 'text/vcard',
'version' => '4.0',
],
],
], $properties);
$this->assertEquals(['https://test/dav/uri'], $contacts);
return true;
})
->andReturn([
'https://test/dav/uri' => [
200 => [
'{'.CardDAVPlugin::NS_CARDDAV.'}address-data' => $card,
'{DAV:}getetag' => $etag,
],
],
]);
});
$pendingBatch = $fake->batch([
$job = new GetMultipleVCard($addressBookSubscription, ['https://test/dav/uri']),
]);
$batch = $pendingBatch->dispatch();
$fake->assertBatched(function (PendingBatch $pendingBatch) {
$this->assertCount(1, $pendingBatch->jobs);
$this->assertInstanceOf(GetMultipleVCard::class, $pendingBatch->jobs->first());
return true;
});
$batch = app(DatabaseBatchRepository::class)->store($pendingBatch);
$job->withBatchId($batch->id)->handle();
$fake->assertDispatched(function (UpdateVCard $updateVCard) use ($etag, $card) {
$dto = $this->getPrivateValue($updateVCard, 'contact');
$this->assertEquals('https://test/dav/uri', $dto->uri);
$this->assertEquals($etag, $dto->etag);
$this->assertEquals($card, $dto->card);
return true;
});
}
/** @test */
public function it_get_cards_mock_http()
{
$fake = Bus::fake();
$user = factory(User::class)->create();
$addressBookSubscription = AddressBookSubscription::factory()->create([
'account_id' => $user->account_id,
'user_id' => $user->id,
]);
$contact = new Contact();
$contact->forceFill([
'first_name' => 'Test',
'uuid' => 'affacde9-b2fe-4371-9acb-6612aaee6971',
'updated_at' => now(),
]);
$card = $this->getCard($contact);
$etag = $this->getEtag($contact, true);
$this->mock(DavClient::class, function (MockInterface $mock) use ($card, $etag) {
$mock->shouldReceive('addressbookMultiget')
->once()
->withArgs(function ($request, $properties, $contacts) {
$this->assertEquals([
'{DAV:}getetag',
[
'name' => '{'.CardDAVPlugin::NS_CARDDAV.'}address-data',
'value' => null,
'attributes' => [
'content-type' => 'text/vcard',
'version' => '4.0',
],
],
], $properties);
$this->assertEquals(['https://test/dav/uri'], $contacts);
return true;
})
->andReturn([
'https://test/dav/uri' => [
200 => [
'{'.CardDAVPlugin::NS_CARDDAV.'}address-data' => $card,
'{DAV:}getetag' => $etag,
],
],
]);
});
$pendingBatch = $fake->batch([
$job = new GetMultipleVCard($addressBookSubscription, ['https://test/dav/uri']),
]);
$batch = $pendingBatch->dispatch();
$fake->assertBatched(function (PendingBatch $pendingBatch) {
$this->assertCount(1, $pendingBatch->jobs);
$this->assertInstanceOf(GetMultipleVCard::class, $pendingBatch->jobs->first());
return true;
});
$batch = app(DatabaseBatchRepository::class)->store($pendingBatch);
$job->withBatchId($batch->id)->handle();
$fake->assertDispatched(function (UpdateVCard $updateVCard) use ($etag, $card) {
$dto = $this->getPrivateValue($updateVCard, 'contact');
$this->assertEquals('https://test/dav/uri', $dto->uri);
$this->assertEquals($etag, $dto->etag);
$this->assertEquals($card, $dto->card);
return true;
});
}
}
+72
View File
@@ -0,0 +1,72 @@
<?php
namespace Tests\Unit\Jobs\Dav;
use Tests\TestCase;
use App\Models\User\User;
use App\Jobs\Dav\GetVCard;
use Tests\Api\DAV\CardEtag;
use App\Jobs\Dav\UpdateVCard;
use App\Models\Contact\Contact;
use Illuminate\Bus\PendingBatch;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Http;
use Illuminate\Bus\DatabaseBatchRepository;
use App\Models\Account\AddressBookSubscription;
use App\Services\DavClient\Utils\Model\ContactDto;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class GetVCardTest extends TestCase
{
use DatabaseTransactions;
use CardEtag;
/** @test */
public function it_get_card()
{
$fake = Bus::fake();
$user = factory(User::class)->create();
$addressBookSubscription = AddressBookSubscription::factory()->create([
'account_id' => $user->account_id,
'user_id' => $user->id,
]);
$contact = new Contact();
$contact->forceFill([
'first_name' => 'Test',
'uuid' => 'affacde9-b2fe-4371-9acb-6612aaee6971',
'updated_at' => now(),
]);
$card = $this->getCard($contact);
$etag = $this->getEtag($contact, true);
Http::fake([
'https://test/dav/uri' => Http::response($card, 200),
]);
$pendingBatch = $fake->batch([
$job = new GetVCard($addressBookSubscription, new ContactDto('https://test/dav/uri', $etag)),
]);
$batch = $pendingBatch->dispatch();
$fake->assertBatched(function (PendingBatch $pendingBatch) {
$this->assertCount(1, $pendingBatch->jobs);
$this->assertInstanceOf(GetVCard::class, $pendingBatch->jobs->first());
return true;
});
$batch = app(DatabaseBatchRepository::class)->store($pendingBatch);
$job->withBatchId($batch->id)->handle();
$fake->assertDispatched(function (UpdateVCard $updateVCard) use ($etag, $card) {
$dto = $this->getPrivateValue($updateVCard, 'contact');
$this->assertEquals('https://test/dav/uri', $dto->uri);
$this->assertEquals($etag, $dto->etag);
$this->assertEquals($card, $dto->card);
return true;
});
}
}
+85
View File
@@ -0,0 +1,85 @@
<?php
namespace Tests\Unit\Jobs\Dav;
use Tests\TestCase;
use App\Models\User\User;
use App\Jobs\Dav\PushVCard;
use Tests\Api\DAV\CardEtag;
use App\Models\Contact\Contact;
use Illuminate\Bus\PendingBatch;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Http;
use Illuminate\Bus\DatabaseBatchRepository;
use App\Models\Account\AddressBookSubscription;
use App\Services\DavClient\Utils\Model\ContactPushDto;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class PushVCardTest extends TestCase
{
use DatabaseTransactions;
use CardEtag;
/**
* @test
* @dataProvider modes
*/
public function it_push_card($mode, $ifmatch)
{
$fake = Bus::fake();
$user = factory(User::class)->create();
$addressBookSubscription = AddressBookSubscription::factory()->create([
'account_id' => $user->account_id,
'user_id' => $user->id,
'uri' => 'https://test/dav',
]);
$contact = new Contact();
$contact->forceFill([
'first_name' => 'John',
'last_name' => 'Doe',
'uuid' => 'affacde9-b2fe-4371-9acb-6612aaee6971',
'updated_at' => '2021-09-01',
]);
$card = $this->getCard($contact);
$etag = $this->getEtag($contact, true);
if ($ifmatch == ['etag']) {
$ifmatch = [$etag];
}
Http::fake(function (Request $request, $options) use ($card, $ifmatch) {
$this->assertEquals('https://test/dav/uri', $request->url());
$this->assertEquals('PUT', $request->method());
$this->assertEquals($ifmatch, $request->header('If-Match'));
return Http::response($card, 200);
});
$pendingBatch = $fake->batch([
$job = new PushVCard($addressBookSubscription, new ContactPushDto('uri', $etag, $card, $mode)),
]);
$batch = $pendingBatch->dispatch();
$fake->assertBatched(function (PendingBatch $pendingBatch) {
$this->assertCount(1, $pendingBatch->jobs);
$this->assertInstanceOf(PushVCard::class, $pendingBatch->jobs->first());
return true;
});
$batch = app(DatabaseBatchRepository::class)->store($pendingBatch);
$job->withBatchId($batch->id)->handle();
}
public function modes(): array
{
return [
[0, []],
[1, ['etag']],
[2, ['*']],
];
}
}
+62
View File
@@ -0,0 +1,62 @@
<?php
namespace Tests\Unit\Jobs\Dav;
use Tests\TestCase;
use App\Models\User\User;
use Tests\Api\DAV\CardEtag;
use App\Jobs\Dav\UpdateVCard;
use App\Models\Contact\Contact;
use Illuminate\Bus\PendingBatch;
use App\Models\Account\AddressBook;
use Illuminate\Support\Facades\Bus;
use Illuminate\Bus\DatabaseBatchRepository;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use App\Services\DavClient\Utils\Model\ContactUpdateDto;
class UpdateVCardTest extends TestCase
{
use DatabaseTransactions;
use CardEtag;
/** @test */
public function it_create_a_contact()
{
$fake = Bus::fake();
$user = factory(User::class)->create();
$addressBook = AddressBook::factory()->create([
'account_id' => $user->account_id,
'user_id' => $user->id,
]);
$contact = new Contact();
$contact->forceFill([
'first_name' => 'Test',
'uuid' => 'affacde9-b2fe-4371-9acb-6612aaee6971',
'updated_at' => now(),
]);
$card = $this->getCard($contact);
$etag = $this->getEtag($contact, true);
$pendingBatch = $fake->batch([
$job = new UpdateVCard($user, $addressBook->name, new ContactUpdateDto('https://test/dav/uricontact1', $etag, $card)),
]);
$batch = $pendingBatch->dispatch();
$fake->assertBatched(function (PendingBatch $pendingBatch) {
$this->assertCount(1, $pendingBatch->jobs);
$this->assertInstanceOf(UpdateVCard::class, $pendingBatch->jobs->first());
return true;
});
$batch = app(DatabaseBatchRepository::class)->store($pendingBatch);
$job->withBatchId($batch->id)->handle();
$this->assertDatabaseHas('contacts', [
'first_name' => 'Test',
'uuid' => 'affacde9-b2fe-4371-9acb-6612aaee6971',
]);
}
}
@@ -4,15 +4,16 @@ namespace Tests\Unit\Services\DavClient\Utils;
use Tests\TestCase;
use Mockery\MockInterface;
use App\Jobs\Dav\PushVCard;
use Tests\Api\DAV\CardEtag;
use Tests\Helpers\DavTester;
use GuzzleHttp\Psr7\Response;
use App\Models\User\SyncToken;
use App\Models\Contact\Contact;
use App\Models\Account\AddressBookSubscription;
use App\Services\DavClient\Utils\Dav\DavClient;
use App\Services\DavClient\Utils\Model\SyncDto;
use App\Services\DavClient\Utils\Model\ContactDto;
use App\Services\DavClient\Utils\Model\ContactPushDto;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use App\Http\Controllers\DAV\Backend\CardDAV\CardDAVBackend;
use App\Services\DavClient\Utils\AddressBookContactsPushMissed;
@@ -48,7 +49,7 @@ class AddressBookContactsPushMissedTest extends TestCase
$mock->shouldReceive('getUuid')
->once()
->withArgs(function ($uri) {
$this->assertEquals('https://test/dav/uuid6', $uri);
$this->assertEquals('uuid6', $uri);
return true;
})
@@ -62,22 +63,25 @@ class AddressBookContactsPushMissedTest extends TestCase
})
->andReturn([
'carddata' => $card,
'uri' => 'https://test/dav/uuid3',
'uri' => 'uuid3',
'etag' => $etag,
]);
});
$tester = (new DavTester('https://test/dav/addressbooks/user@test.com/contacts/'));
$tester->addResponse('https://test/dav/uuid3', new Response(200, ['Etag' => $etag]), $card, 'PUT', ['If-Match' => '*']);
$tester = new DavTester();
$client = app(DavClient::class)->init([], $tester->getClient());
$client = new DavClient([], $tester->getClient());
(new AddressBookContactsPushMissed())
$batchs = (new AddressBookContactsPushMissed())
->execute(new SyncDto($subscription, $client, $backend), [], collect([
'https://test/dav/uuid6' => new ContactDto('https://test/dav/uuid6', $etag),
]), collect([$contact]))
->wait();
'uuid6' => new ContactDto('uuid6', $etag),
]), collect([$contact]));
$tester->assert();
$this->assertCount(1, $batchs);
$batch = $batchs->first();
$this->assertInstanceOf(PushVCard::class, $batch);
$dto = $this->getPrivateValue($batch, 'contact');
$this->assertInstanceOf(ContactPushDto::class, $dto);
$this->assertEquals('uuid3', $dto->uri);
$this->assertEquals(2, $dto->mode);
}
}
@@ -4,16 +4,17 @@ namespace Tests\Unit\Services\DavClient\Utils;
use Tests\TestCase;
use Mockery\MockInterface;
use App\Jobs\Dav\PushVCard;
use Illuminate\Support\Str;
use Tests\Api\DAV\CardEtag;
use Tests\Helpers\DavTester;
use GuzzleHttp\Psr7\Response;
use App\Models\User\SyncToken;
use App\Models\Contact\Contact;
use App\Models\Account\AddressBookSubscription;
use App\Services\DavClient\Utils\Dav\DavClient;
use App\Services\DavClient\Utils\Model\SyncDto;
use App\Services\DavClient\Utils\Model\ContactDto;
use App\Services\DavClient\Utils\Model\ContactPushDto;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use App\Services\DavClient\Utils\AddressBookContactsPush;
use App\Http\Controllers\DAV\Backend\CardDAV\CardDAVBackend;
@@ -48,7 +49,7 @@ class AddressBookContactsPushTest extends TestCase
$backend = $this->mock(CardDAVBackend::class, function (MockInterface $mock) use ($card, $etag) {
$mock->shouldReceive('getCard')
->withArgs(function ($name, $uri) {
$this->assertEquals($uri, 'https://test/dav/uricontact2');
$this->assertEquals($uri, 'uricontact2');
return true;
})
@@ -65,20 +66,23 @@ class AddressBookContactsPushTest extends TestCase
->andReturn('uricontact1');
});
$tester = (new DavTester('https://test/dav/addressbooks/user@test.com/contacts/'));
$tester->addResponse('https://test/dav/uricontact2', new Response(200, ['Etag' => $etag]), $card, 'PUT');
$tester = new DavTester();
$client = app(DavClient::class)->init([], $tester->getClient());
$client = new DavClient([], $tester->getClient());
(new AddressBookContactsPush())
$batchs = (new AddressBookContactsPush())
->execute(new SyncDto($subscription, $client, $backend), collect([
'https://test/dav/uricontact1' => new ContactDto('https://test/dav/uricontact1', $etag),
]), [
'added' => ['https://test/dav/uricontact2'],
])
->wait();
'added' => ['uricontact2'],
]);
$tester->assert();
$this->assertCount(1, $batchs);
$batch = $batchs->first();
$this->assertInstanceOf(PushVCard::class, $batch);
$dto = $this->getPrivateValue($batch, 'contact');
$this->assertInstanceOf(ContactPushDto::class, $dto);
$this->assertEquals('uricontact2', $dto->uri);
$this->assertEquals(0, $dto->mode);
}
/** @test */
@@ -106,7 +110,7 @@ class AddressBookContactsPushTest extends TestCase
$backend = $this->mock(CardDAVBackend::class, function (MockInterface $mock) use ($card, $etag) {
$mock->shouldReceive('getUuid')
->withArgs(function ($uri) {
$this->assertStringStartsWith('https://test/dav/uricontact', $uri);
$this->assertStringContainsString('uricontact', $uri);
return true;
})
@@ -115,7 +119,7 @@ class AddressBookContactsPushTest extends TestCase
});
$mock->shouldReceive('getCard')
->withArgs(function ($name, $uri) {
$this->assertEquals($uri, 'https://test/dav/uricontact2');
$this->assertEquals($uri, 'uricontact2');
return true;
})
@@ -125,19 +129,22 @@ class AddressBookContactsPushTest extends TestCase
]);
});
$tester = (new DavTester('https://test/dav/addressbooks/user@test.com/contacts/'));
$tester->addResponse('https://test/dav/uricontact2', new Response(200, ['Etag' => $etag]), $card, 'PUT', ['If-Match' => $etag]);
$tester = new DavTester();
$client = app(DavClient::class)->init([], $tester->getClient());
$client = new DavClient([], $tester->getClient());
(new AddressBookContactsPush())
$batchs = (new AddressBookContactsPush())
->execute(new SyncDto($subscription, $client, $backend), collect([
'https://test/dav/uricontact1' => new ContactDto('https://test/dav/uricontact1', $etag),
]), [
'modified' => ['https://test/dav/uricontact2'],
])
->wait();
'modified' => ['uricontact2'],
]);
$tester->assert();
$this->assertCount(1, $batchs);
$batch = $batchs->first();
$this->assertInstanceOf(PushVCard::class, $batch);
$dto = $this->getPrivateValue($batch, 'contact');
$this->assertInstanceOf(ContactPushDto::class, $dto);
$this->assertEquals('uricontact2', $dto->uri);
$this->assertEquals(1, $dto->mode);
}
}
@@ -8,6 +8,7 @@ use Tests\Api\DAV\CardEtag;
use Tests\Helpers\DavTester;
use App\Models\User\SyncToken;
use App\Models\Contact\Contact;
use App\Jobs\Dav\GetMultipleVCard;
use App\Models\Account\AddressBookSubscription;
use App\Services\DavClient\Utils\Dav\DavClient;
use App\Services\DavClient\Utils\Model\SyncDto;
@@ -61,21 +62,22 @@ class AddressBookContactsUpdaterMissedTest extends TestCase
->andReturn($etag);
});
$tester = (new DavTester('https://test/dav/addressbooks/user@test.com/contacts/'));
$tester->addressMultiGet($etag, $card, 'https://test/dav/uuid2');
$tester = new DavTester();
$client = app(DavClient::class)->init([], $tester->getClient());
$client = new DavClient([], $tester->getClient());
(new AddressBookContactsUpdaterMissed())
$batchs = (new AddressBookContactsUpdaterMissed())
->execute(new SyncDto($subscription, $client, $backend), collect([
[
'uuid' => 'uuid1',
],
]), collect([
'https://test/dav/uuid2' => new ContactDto('https://test/dav/uuid2', $etag),
]))
->wait();
]));
$tester->assert();
$this->assertCount(1, $batchs);
$batch = $batchs->first();
$this->assertInstanceOf(GetMultipleVCard::class, $batch);
$hrefs = $this->getPrivateValue($batch, 'hrefs');
$this->assertEquals(['https://test/dav/uuid2'], $hrefs);
}
}
@@ -3,12 +3,13 @@
namespace Tests\Unit\Services\DavClient\Utils;
use Tests\TestCase;
use App\Jobs\Dav\GetVCard;
use Mockery\MockInterface;
use Tests\Api\DAV\CardEtag;
use Tests\Helpers\DavTester;
use GuzzleHttp\Psr7\Response;
use App\Models\User\SyncToken;
use App\Models\Contact\Contact;
use App\Jobs\Dav\GetMultipleVCard;
use App\Models\Account\AddressBookSubscription;
use App\Services\DavClient\Utils\Dav\DavClient;
use App\Services\DavClient\Utils\Model\SyncDto;
@@ -55,18 +56,19 @@ class AddressBookContactsUpdaterTest extends TestCase
->andReturn($etag);
});
$tester = (new DavTester('https://test/dav/addressbooks/user@test.com/contacts/'));
$tester->addressMultiGet($etag, $card, 'https://test/dav/uuid2');
$tester = new DavTester();
$client = app(DavClient::class)->init([], $tester->getClient());
$client = new DavClient([], $tester->getClient());
(new AddressBookContactsUpdater())
$batchs = (new AddressBookContactsUpdater())
->execute(new SyncDto($subscription, $client, $backend), collect([
'https://test/dav/uuid2' => new ContactDto('https://test/dav/uuid2', $etag),
]))
->wait();
]));
$tester->assert();
$this->assertCount(1, $batchs);
$batch = $batchs->first();
$this->assertInstanceOf(GetMultipleVCard::class, $batch);
$hrefs = $this->getPrivateValue($batch, 'hrefs');
$this->assertEquals(['https://test/dav/uuid2'], $hrefs);
}
/** @test */
@@ -121,17 +123,19 @@ class AddressBookContactsUpdaterTest extends TestCase
->andReturn($etag);
});
$tester = (new DavTester('https://test/dav/addressbooks/user@test.com/contacts/'));
$tester->addResponse('https://test/dav/uuid2', new Response(200, [], $card), null, 'GET');
$tester = new DavTester();
$client = app(DavClient::class)->init([], $tester->getClient());
$client = new DavClient([], $tester->getClient());
(new AddressBookContactsUpdater())
$batchs = (new AddressBookContactsUpdater())
->execute(new SyncDto($subscription, $client, $backend), collect([
'https://test/dav/uuid2' => new ContactDto('https://test/dav/uuid2', $etag),
]))
->wait();
]));
$tester->assert();
$this->assertCount(1, $batchs);
$batch = $batchs->first();
$this->assertInstanceOf(GetVCard::class, $batch);
$dto = $this->getPrivateValue($batch, 'contact');
$this->assertInstanceOf(ContactDto::class, $dto);
$this->assertEquals('https://test/dav/uuid2', $dto->uri);
}
}
@@ -21,7 +21,7 @@ class AddressBookGetterTest extends TestCase
->addressBookBaseUri()
->capabilities()
->displayName();
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$result = (new AddressBookGetter())
->execute($client);
@@ -47,7 +47,7 @@ class AddressBookGetterTest extends TestCase
$tester = (new DavTester())
->serviceUrl()
->optionsFail();
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$this->expectException(DavServerNotCompliantException::class);
(new AddressBookGetter())
@@ -62,7 +62,7 @@ class AddressBookGetterTest extends TestCase
->optionsOk()
->userPrincipalEmpty();
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$this->expectException(DavServerNotCompliantException::class);
(new AddressBookGetter())
@@ -78,7 +78,7 @@ class AddressBookGetterTest extends TestCase
->userPrincipal()
->addressbookEmpty();
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$this->expectException(DavServerNotCompliantException::class);
(new AddressBookGetter())
@@ -94,7 +94,7 @@ class AddressBookGetterTest extends TestCase
->userPrincipal()
->addressbookHome()
->resourceTypeHomeOnly();
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$this->expectException(DavClientException::class);
(new AddressBookGetter())
@@ -9,7 +9,9 @@ use Tests\Helpers\DavTester;
use GuzzleHttp\Psr7\Response;
use App\Models\User\SyncToken;
use App\Models\Contact\Contact;
use GuzzleHttp\Promise\Promise;
use Illuminate\Bus\PendingBatch;
use App\Jobs\Dav\GetMultipleVCard;
use Illuminate\Support\Facades\Bus;
use App\Models\Account\AddressBookSubscription;
use App\Services\DavClient\Utils\Dav\DavClient;
use App\Services\DavClient\Utils\Model\SyncDto;
@@ -28,6 +30,8 @@ class AddressBookSynchronizerTest extends TestCase
/** @test */
public function it_sync_empty_changes()
{
Bus::fake();
$this->mock(AddressBookContactsUpdater::class, function (MockInterface $mock) {
$mock->shouldReceive('execute')
->once()
@@ -39,7 +43,7 @@ class AddressBookSynchronizerTest extends TestCase
$tester = (new DavTester('https://test/dav/addressbooks/user@test.com/contacts/'))
->getSynctoken($subscription->syncToken);
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
(new AddressBookSynchronizer())
->execute(new SyncDto($subscription, $client, $backend));
@@ -50,6 +54,8 @@ class AddressBookSynchronizerTest extends TestCase
/** @test */
public function it_sync_no_changes()
{
Bus::fake();
$this->mock(AddressBookContactsUpdater::class, function (MockInterface $mock) {
$mock->shouldReceive('execute')
->once()
@@ -63,7 +69,7 @@ class AddressBookSynchronizerTest extends TestCase
$tester->getSynctoken('"test21"')
->getSyncCollection('test20');
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
(new AddressBookSynchronizer())
->execute(new SyncDto($subscription, $client, $backend));
@@ -74,6 +80,8 @@ class AddressBookSynchronizerTest extends TestCase
/** @test */
public function it_sync_changes_added_local_contact()
{
Bus::fake();
$subscription = $this->getSubscription();
$backend = new CardDAVBackend($subscription->user);
@@ -87,7 +95,7 @@ class AddressBookSynchronizerTest extends TestCase
$tester->getSynctoken('"token"')
->getSyncCollection('token', '"test2"');
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$sync = new SyncDto($subscription, $client, $backend);
$this->mock(AddressBookContactsUpdater::class, function (MockInterface $mock) use ($sync) {
@@ -100,9 +108,7 @@ class AddressBookSynchronizerTest extends TestCase
return true;
})
->andReturn(new Promise(function () {
return true;
}));
->andReturn(collect());
});
(new AddressBookSynchronizer())
@@ -111,9 +117,48 @@ class AddressBookSynchronizerTest extends TestCase
$tester->assert();
}
/** @test */
public function it_sync_changes_added_local_contact_batched()
{
Bus::fake();
$subscription = $this->getSubscription();
$backend = new CardDAVBackend($subscription->user);
$contact = factory(Contact::class)->create([
'account_id' => $subscription->account_id,
'address_book_id' => $subscription->address_book_id,
'uuid' => 'd403af1c-8492-4e9b-9833-cf18c795dfa9',
]);
$tester = (new DavTester('https://test/dav/addressbooks/user@test.com/contacts/'));
$tester->getSynctoken('"token"')
->getSyncCollection('token', '"test2"');
$client = app(DavClient::class)->init([], $tester->getClient());
$sync = new SyncDto($subscription, $client, $backend);
(new AddressBookSynchronizer())
->execute($sync);
$tester->assert();
Bus::assertBatched(function (PendingBatch $batch) {
$this->assertCount(1, $batch->jobs);
$job = $batch->jobs[0];
$this->assertInstanceOf(GetMultipleVCard::class, $job);
$this->assertEquals(['https://test/dav/addressbooks/user@test.com/contacts/uuid'], $this->getPrivateValue($job, 'hrefs'));
return true;
});
}
/** @test */
public function it_forcesync_changes_added_local_contact()
{
Bus::fake();
$subscription = $this->getSubscription();
$backend = new CardDAVBackend($subscription->user);
@@ -142,7 +187,7 @@ class AddressBookSynchronizerTest extends TestCase
'</d:prop>'.
"</card:addressbook-query>\n", 'REPORT');
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$sync = new SyncDto($subscription, $client, $backend);
$this->mock(AddressBookContactsUpdaterMissed::class, function (MockInterface $mock) use ($sync, $contact, $etag) {
@@ -156,16 +201,12 @@ class AddressBookSynchronizerTest extends TestCase
return true;
})
->andReturn(new Promise(function () {
return true;
}));
->andReturn(collect());
});
$this->mock(AddressBookContactsPushMissed::class, function (MockInterface $mock) {
$mock->shouldReceive('execute')
->once()
->andReturn(new Promise(function () {
return true;
}));
->andReturn(collect());
});
(new AddressBookSynchronizer())
@@ -174,6 +215,58 @@ class AddressBookSynchronizerTest extends TestCase
$tester->assert();
}
/** @test */
public function it_forcesync_changes_added_local_contact_batched()
{
Bus::fake();
$subscription = $this->getSubscription();
$backend = new CardDAVBackend($subscription->user);
$contact = factory(Contact::class)->create([
'account_id' => $subscription->account_id,
'address_book_id' => $subscription->address_book_id,
'uuid' => 'd403af1c-8492-4e9b-9833-cf18c795dfa9',
]);
$etag = $this->getEtag($contact, true);
$tester = (new DavTester('https://test/dav/addressbooks/user@test.com/contacts/'));
$tester->addResponse('https://test/dav/addressbooks/user@test.com/contacts/', new Response(200, [], $tester->multistatusHeader().
'<d:response>'.
'<d:href>https://test/dav/uuid1</d:href>'.
'<d:propstat>'.
'<d:prop>'.
"<d:getetag>$etag</d:getetag>".
'</d:prop>'.
'<d:status>HTTP/1.1 200 OK</d:status>'.
'</d:propstat>'.
'</d:response>'.
'</d:multistatus>'), '<?xml version="1.0" encoding="UTF-8"?>'."\n".
'<card:addressbook-query xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">'.
'<d:prop>'.
'<d:getetag/>'.
'</d:prop>'.
"</card:addressbook-query>\n", 'REPORT');
$client = app(DavClient::class)->init([], $tester->getClient());
$sync = new SyncDto($subscription, $client, $backend);
(new AddressBookSynchronizer())
->execute($sync, true);
$tester->assert();
Bus::assertBatched(function (PendingBatch $batch) {
$this->assertCount(1, $batch->jobs);
$job = $batch->jobs[0];
$this->assertInstanceOf(GetMultipleVCard::class, $job);
$this->assertEquals(['https://test/dav/uuid1'], $this->getPrivateValue($job, 'hrefs'));
return true;
});
}
private function getSubscription()
{
$subscription = AddressBookSubscription::factory()->create();
@@ -5,6 +5,8 @@ namespace Tests\Unit\Services\DavClient\Utils\Dav;
use Tests\TestCase;
use Tests\Helpers\DavTester;
use GuzzleHttp\Psr7\Response;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;
use GuzzleHttp\Exception\ServerException;
use App\Services\DavClient\Utils\Dav\DavClient;
use Illuminate\Foundation\Testing\DatabaseTransactions;
@@ -14,29 +16,17 @@ class DavClientTest extends TestCase
{
use DatabaseTransactions;
/** @test */
public function it_creates_client()
{
$client = new DavClient([
'base_uri' => 'test',
'username' => 'user',
'password' => 'pass',
]);
$this->assertInstanceOf(\Sabre\DAV\Xml\Service::class, $client->xml);
}
/** @test */
public function it_fails_if_no_baseuri()
{
$this->expectException(\InvalidArgumentException::class);
new DavClient([]);
app(DavClient::class)->init([]);
}
/** @test */
public function it_accept_guzzle_client()
{
$client = new DavClient([], new \GuzzleHttp\Client());
$client = app(DavClient::class)->init([], new \GuzzleHttp\Client());
$this->assertInstanceOf(DavClient::class, $client);
}
@@ -47,7 +37,7 @@ class DavClientTest extends TestCase
->addResponse('https://test', new Response(200, []), null, 'OPTIONS')
->addResponse('https://test', new Response(200, ['Dav' => 'test']), null, 'OPTIONS')
->addResponse('https://test', new Response(200, ['Dav' => ' test ']), null, 'OPTIONS');
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$result = $client->options();
$this->assertEquals([], $result);
@@ -66,7 +56,7 @@ class DavClientTest extends TestCase
{
$tester = (new DavTester())
->serviceUrl();
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$result = $client->getServiceUrl();
@@ -80,7 +70,7 @@ class DavClientTest extends TestCase
$tester = (new DavTester())
->addResponse('https://test/.well-known/carddav', new Response(200), null, 'GET')
->nonStandardServiceUrl();
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$result = $client->getServiceUrl();
@@ -94,7 +84,7 @@ class DavClientTest extends TestCase
$tester = (new DavTester())
->addResponse('https://test/.well-known/carddav', new Response(404), null, 'GET')
->nonStandardServiceUrl();
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$result = $client->getServiceUrl();
@@ -107,7 +97,7 @@ class DavClientTest extends TestCase
{
$tester = (new DavTester())
->addResponse('https://test/.well-known/carddav', new Response(500), null, 'GET');
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$this->expectException(ServerException::class);
$client->getServiceUrl();
@@ -117,7 +107,7 @@ class DavClientTest extends TestCase
public function it_get_base_uri()
{
$tester = (new DavTester());
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$result = $client->getBaseUri();
@@ -132,7 +122,7 @@ class DavClientTest extends TestCase
public function it_set_base_uri()
{
$tester = (new DavTester());
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$result = $client->setBaseUri('https://new')
->getBaseUri();
@@ -162,7 +152,7 @@ class DavClientTest extends TestCase
'</d:prop>'.
"</d:propfind>\n", 'PROPFIND');
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$result = $client->propFind('https://test/test', ['{DAV:}test']);
@@ -194,7 +184,7 @@ class DavClientTest extends TestCase
'</d:prop>'.
"</d:propfind>\n", 'PROPFIND');
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$result = $client->getProperty('{DAV:}test', 'https://test/test');
@@ -231,7 +221,7 @@ class DavClientTest extends TestCase
'</d:prop>'.
"</d:propfind>\n", 'PROPFIND');
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$result = $client->getSupportedReportSet();
@@ -265,7 +255,7 @@ class DavClientTest extends TestCase
'</d:prop>'.
"</d:sync-collection>\n", 'REPORT');
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$result = $client->syncCollectionAsync('https://test/test', ['{DAV:}test'], '')
->wait();
@@ -308,7 +298,7 @@ class DavClientTest extends TestCase
'</d:prop>'.
"</d:sync-collection>\n", 'REPORT');
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$result = $client->syncCollectionAsync('https://test/test', ['{DAV:}test'], '"00000-abcd0"')
->wait();
@@ -328,9 +318,8 @@ class DavClientTest extends TestCase
/** @test */
public function it_run_addressbook_multiget_report()
{
$tester = (new DavTester());
$tester->addResponse('https://test/test', new Response(200, [], $tester->multistatusHeader().
Http::fake([
'https://test/*' => Http::response(DavTester::multistatusHeader().
'<d:response>'.
'<d:href>href</d:href>'.
'<d:propstat>'.
@@ -341,22 +330,27 @@ class DavClientTest extends TestCase
'<d:status>HTTP/1.1 200 OK</d:status>'.
'</d:propstat>'.
'</d:response>'.
'</d:multistatus>'), '<?xml version="1.0" encoding="UTF-8"?>'."\n".
'<card:addressbook-multiget xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">'.
'<d:prop>'.
'<d:test/>'.
'</d:prop>'.
'<d:href>https://test/contacts/1</d:href>'.
"</card:addressbook-multiget>\n", 'REPORT');
'</d:multistatus>'),
]);
$client = new DavClient([], $tester->getClient());
$result = $client->addressbookMultigetAsync('https://test/test', ['{DAV:}test'], [
$result = app(DavClient::class)->addressbookMultiget(Http::baseUrl('https://test/test'), ['{DAV:}test'], [
'https://test/contacts/1',
])
->wait();
]);
Http::assertSent(function (Request $request) {
$this->assertEquals('https://test/test/', $request->url());
$this->assertEquals('REPORT', $request->method());
$this->assertEquals('<?xml version="1.0" encoding="UTF-8"?>'."\n".
'<card:addressbook-multiget xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">'.
'<d:prop>'.
'<d:test/>'.
'</d:prop>'.
'<d:href>https://test/contacts/1</d:href>'.
"</card:addressbook-multiget>\n", $request->body());
return true;
});
$tester->assert();
$this->assertEquals([
'href' => [
200 => [
@@ -390,7 +384,7 @@ class DavClientTest extends TestCase
'</d:prop>'.
"</card:addressbook-query>\n", 'REPORT');
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$result = $client->addressbookQueryAsync('https://test/test', ['{DAV:}test'])
->wait();
@@ -430,7 +424,7 @@ class DavClientTest extends TestCase
' </d:set>'."\n".
"</d:propertyupdate>\n", 'PROPPATCH');
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$result = $client->propPatchAsync('https://test/test', ['{DAV:}test' => 'value'])
->wait();
@@ -470,11 +464,11 @@ class DavClientTest extends TestCase
' </d:set>'."\n".
"</d:propertyupdate>\n", 'PROPPATCH');
$client = new DavClient([], $tester->getClient());
$client = app(DavClient::class)->init([], $tester->getClient());
$this->expectException(DavClientException::class);
$this->expectExceptionMessage('PROPPATCH failed. The following properties errored: {DAV:}test (405), {DAV:}excerpt (500)');
$result = $client->propPatchAsync('https://test/test', [
$client->propPatchAsync('https://test/test', [
'{DAV:}test' => 'value',
'{DAV:}excerpt' => 'value',
])
@@ -0,0 +1,31 @@
<?php
namespace Tests\Unit\Services\DavClient\Utils\Model;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use App\Services\DavClient\Utils\Model\ContactUpdateDto;
class ContactUpdateDtoTest extends TestCase
{
use DatabaseTransactions;
/** @test */
public function it_create_dto_string()
{
$dto = new ContactUpdateDto('uri', 'etag', 'card');
$this->assertEquals('uri', $dto->uri);
$this->assertEquals('etag', $dto->etag);
$this->assertEquals('card', $dto->card);
}
/** @test */
public function it_create_dto_resource()
{
$resource = fopen(__DIR__.'/stub.vcf', 'r');
$dto = new ContactUpdateDto('uri', 'etag', $resource);
$this->assertEquals('uri', $dto->uri);
$this->assertEquals('etag', $dto->etag);
$this->assertEquals('card', $dto->card);
}
}
@@ -0,0 +1 @@
card