Skip to content

Commit

Permalink
tests
Browse files Browse the repository at this point in the history
  • Loading branch information
asbiin committed Jul 14, 2023
1 parent 5ce031e commit f030cff
Show file tree
Hide file tree
Showing 17 changed files with 706 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel,
}

/**
* Prepare datas for this contact.
* Prepare data for this contact.
*/
public function prepareCard(Contact $contact): array
{
Expand Down
4 changes: 2 additions & 2 deletions app/Domains/Contact/DavClient/Jobs/GetMultipleVCard.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ public function handle(): void
return; // @codeCoverageIgnore
}

$datas = $this->subscription->getClient()
$data = $this->subscription->getClient()
->addressbookMultiget([
'{DAV:}getetag',
$this->getAddressDataProperty(),
], $this->hrefs);

collect($datas)
collect($data)
->filter(fn (array $contact): bool => isset($contact[200]))
->each(fn (array $contact, $href) => $this->updateVCard($contact, $href));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public function __construct(
*/
public function handle(): void
{
Log::withContext([
'addressbook_subscription_id' => $this->subscription->id,
]);

try {
app(SynchronizeAddressBook::class)->execute([
'account_id' => $this->subscription->user->account_id,
Expand All @@ -41,5 +45,7 @@ public function handle(): void
}
$this->subscription->last_synchronized_at = now();
$this->subscription->save();

Log::withoutContext();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -221,14 +221,14 @@ private function getSupportedAddressData(): array
{
// get the supported card format
$addressData = collect($this->client->getProperty('{'.CardDAVPlugin::NS_CARDDAV.'}supported-address-data'));
$datas = $addressData->firstWhere('attributes.version', '4.0');
if (! $datas) {
$datas = $addressData->firstWhere('attributes.version', '3.0');
$data = $addressData->firstWhere('attributes.version', '4.0');
if (! $data) {
$data = $addressData->firstWhere('attributes.version', '3.0');
}

if (! $datas) {
if (! $data) {
// It should not happen !
$datas = [
$data = [
'attributes' => [
'content-type' => 'text/vcard',
'version' => '4.0',
Expand All @@ -238,8 +238,8 @@ private function getSupportedAddressData(): array

return [
'addressData' => [
'content-type' => Arr::get($datas, 'attributes.content-type'),
'version' => Arr::get($datas, 'attributes.version'),
'content-type' => Arr::get($data, 'attributes.content-type'),
'version' => Arr::get($data, 'attributes.version'),
],
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,8 @@ public function options(string $url = ''): array
* Performs an actual HTTP request, and returns the result.
*
* @param string|null|resource|\Psr\Http\Message\StreamInterface $body
*
* @throws \Illuminate\Http\Client\RequestException
*/
public function request(string $method, string $url = '', mixed $body = null, array $headers = [], array $options = []): Response
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
namespace App\Domains\Contact\DavClient\Services\Utils\Dav;

use GuzzleHttp\Psr7\Uri;
use Http\Client\Exception\RequestException;
use Illuminate\Support\Collection;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Http;
use Safe\Exceptions\UrlException;
use function Safe\parse_url;

class ServiceUrlQuery
{
Expand All @@ -16,33 +18,38 @@ class ServiceUrlQuery
*/
public function execute(string $name, bool $https, string $baseUri, DavClient $client): ?string
{
try {
$host = \Safe\parse_url($baseUri, PHP_URL_HOST);
} catch (\Safe\Exceptions\UrlException $e) {
return null;
}

$entries = $this->dns_get_record($name.'.'.$host, DNS_SRV);
if (($host = $this->parseUrl($baseUri)) !== null) {
$entries = Http::getDnsRecord($name.'.'.$host, DNS_SRV);

if ($entries && $entries->count() > 0) {
$entries = collect($entries)
->groupBy('pri')
->sortKeys()
->first()
->sortByDesc('weight');
if (optional($entries)->count()) {
$entries = $entries
->groupBy('pri')
->sortKeys()
->sortByDesc('weight')
->flatten(1);

foreach ($entries as $entry) {
try {
return $this->getUri($entry, $https, $client);
} catch (RequestException $e) {
// no exception
foreach ($entries as $entry) {
try {
return $this->getUri($entry, $https, $client);
} catch (RequestException $e) {

Check failure on line 34 in app/Domains/Contact/DavClient/Services/Utils/Dav/ServiceUrlQuery.php

View workflow job for this annotation

GitHub Actions / phpstan

Dead catch - Illuminate\Http\Client\RequestException is never thrown in the try block.
// if any exception occurs, it will try the next entry.
}
}
}
}

return null;
}

private function parseUrl(string $baseUri): ?string
{
try {
return parse_url($baseUri, PHP_URL_HOST);
} catch (UrlException $e) {
return null;
}
}

/**
* Get uri from entry.
*
Expand All @@ -60,15 +67,4 @@ private function getUri(array $entry, bool $https, DavClient $client): string

return (string) $uri;
}

private function dns_get_record(string $hostname, int $type = DNS_ANY, ?array &$authns = null, ?array &$addtl = null, bool $raw = false): ?Collection
{
error_clear_last();
$result = \dns_get_record($hostname, $type, $authns, $addtl, $raw);
if ($result === false) {
return null;
}

return collect($result);
}
}
5 changes: 4 additions & 1 deletion app/Models/Contact.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Laravel\Scout\Attributes\SearchUsingFullText;
use Laravel\Scout\Attributes\SearchUsingPrefix;
Expand Down Expand Up @@ -386,7 +387,9 @@ protected function name(): Attribute
return NameHelper::formatContactName(Auth::user(), $this);
}

return $attributes['first_name'].' '.$attributes['last_name'];
$lastName = Arr::get($attributes, 'last_name');

return Arr::get($attributes, 'first_name').$lastName ? ' '.$lastName : '';
}
);
}
Expand Down
15 changes: 15 additions & 0 deletions app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
Expand Down Expand Up @@ -62,6 +63,20 @@ public function register()
});
}

if (! Http::hasMacro('getDnsRecord')) {
Http::macro('getDnsRecord', function (string $hostname, int $type): ?Collection {
try {
if (($entries = \Safe\dns_get_record($hostname, $type)) !== null) {
return collect($entries);
}
} catch (\Safe\Exceptions\NetworkException) {
// ignore
}

return null;
});
}

if (! Collection::hasMacro('sortByCollator')) {
Collection::macro('sortByCollator', function (callable|string $callback) {
/** @var Collection */
Expand Down
5 changes: 4 additions & 1 deletion tests/Helpers/DavTester.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Domains\Contact\DavClient\Services\Utils\Dav\DavClient;
use GuzzleHttp\Promise\PromiseInterface;
use Illuminate\Http\Client\Factory;
use Illuminate\Http\Client\Request;
use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http;
Expand All @@ -17,6 +18,8 @@ class DavTester extends TestCase

public string $baseUri = '';

public ?Factory $http = null;

public function __construct(string $baseUri = 'https://test')
{
$this->baseUri = $baseUri;
Expand All @@ -29,7 +32,7 @@ public function client(): DavClient

public function fake()
{
Http::fake(function ($request) {
$this->http = Http::fake(function ($request) {
return $this->responses[$this->current++]['response'];
});

Expand Down
9 changes: 5 additions & 4 deletions tests/Unit/Domains/Contact/DAV/CardEtag.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ protected function getEtag($obj, bool $quotes = false)
protected function getCard(Contact $contact, bool $realFormat = false): string
{
$contact = $contact->refresh();
$url = route('contact.show', [
'vault' => $contact->vault_id,
'contact' => $contact->id,
]);
$url = $contact->vault_id
? route('contact.show', [
'vault' => $contact->vault_id,
'contact' => $contact->id,
]) : null;
$sabreversion = \Sabre\VObject\Version::VERSION;
$timestamp = $contact->updated_at->format('Ymd\THis\Z');

Expand Down
67 changes: 67 additions & 0 deletions tests/Unit/Domains/Contact/DAV/Jobs/UpdateVCardTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace Tests\Unit\Domains\Contact\DAV\Jobs;

use App\Domains\Contact\Dav\Jobs\UpdateVCard;
use App\Models\Contact;
use App\Models\User;
use App\Models\Vault;
use Illuminate\Bus\DatabaseBatchRepository;
use Illuminate\Bus\PendingBatch;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Bus;
use Tests\TestCase;
use Tests\Unit\Domains\Contact\DAV\CardEtag;

class UpdateVCardTest extends TestCase
{
use DatabaseTransactions;
use CardEtag;

/** @test */
public function it_create_a_contact()
{
$fake = Bus::fake();

$user = User::factory()->create();
$vault = $this->createVaultUser($user, Vault::PERMISSION_MANAGE);

$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([
'account_id' => $vault->account_id,
'author_id' => $user->id,
'vault_id' => $vault->id,
'uri' => 'https://test/dav/uricontact1',
'etag' => $etag,
'card' => $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',
'vcard' => $card,
'distant_etag' => $etag,
]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Tests\Unit\Domains\Contact\DavClient\Jobs;

use App\Domains\Contact\DavClient\Jobs\DeleteMultipleVCard;
use App\Domains\Contact\DavClient\Jobs\DeleteVCard;
use App\Models\AddressBookSubscription;
use Illuminate\Bus\DatabaseBatchRepository;
use Illuminate\Bus\PendingBatch;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Bus;
use Tests\TestCase;

class DeleteMultipleVCardTest extends TestCase
{
use DatabaseTransactions;

/** @test */
public function it_delete_cards()
{
$fake = Bus::fake();

$addressBookSubscription = AddressBookSubscription::factory()->create();

$pendingBatch = $fake->batch([
$job = new DeleteMultipleVCard($addressBookSubscription, ['https://test/dav/uri']),
]);
$batch = $pendingBatch->dispatch();

$fake->assertBatched(function (PendingBatch $pendingBatch) {
$this->assertCount(1, $pendingBatch->jobs);
$this->assertInstanceOf(DeleteMultipleVCard::class, $pendingBatch->jobs->first());

return true;
});

$batch = app(DatabaseBatchRepository::class)->store($pendingBatch);
$job->withBatchId($batch->id)->handle();

$fake->assertDispatched(function (DeleteVCard $updateVCard) {
$uri = $this->getPrivateValue($updateVCard, 'uri');
$this->assertEquals('https://test/dav/uri', $uri);

return true;
});
}
}
Loading

0 comments on commit f030cff

Please sign in to comment.