diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 54dd1a88d1b..ebe38f15d3a 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -38,6 +38,7 @@ protected function commands() * * @param \Illuminate\Console\Scheduling\Schedule $schedule * @return void + * @codeCoverageIgnore */ protected function schedule(Schedule $schedule) { @@ -50,22 +51,25 @@ protected function schedule(Schedule $schedule) $this->scheduleCommand($schedule, 'monica:clean', 'daily'); $this->scheduleCommand($schedule, 'monica:updategravatars', 'weekly'); if (config('trustedproxy.cloudflare')) { - $this->scheduleCommand($schedule, 'cloudflare:reload', 'daily'); // @codeCoverageIgnore + $this->scheduleCommand($schedule, 'cloudflare:reload', 'daily'); } + $this->scheduleCommand($schedule, 'model:prune', 'daily'); } /** * Define a new schedule command with a frequency. + * + * @codeCoverageIgnore */ private function scheduleCommand(Schedule $schedule, string $command, $frequency) { $schedule->command($command)->when(function () use ($command, $frequency) { - $event = CronEvent::command($command); // @codeCoverageIgnore - if ($frequency) { // @codeCoverageIgnore - $event = $event->$frequency(); // @codeCoverageIgnore + $event = CronEvent::command($command); + if ($frequency) { + $event = $event->$frequency(); } - return $event->isDue(); // @codeCoverageIgnore + return $event->isDue(); }); } } diff --git a/app/Http/Controllers/DAV/Backend/CalDAV/CalDAVBirthdays.php b/app/Http/Controllers/DAV/Backend/CalDAV/CalDAVBirthdays.php index 9c01e8a2dd1..efd8d61a3bf 100644 --- a/app/Http/Controllers/DAV/Backend/CalDAV/CalDAVBirthdays.php +++ b/app/Http/Controllers/DAV/Backend/CalDAV/CalDAVBirthdays.php @@ -142,6 +142,17 @@ public function getObjects($collectionId) }); } + /** + * Returns the collection of deleted birthdays. + * + * @param string|null $collectionId + * @return \Illuminate\Support\Collection + */ + public function getDeletedObjects($collectionId) + { + return collect(); + } + /** * @return string|null */ diff --git a/app/Http/Controllers/DAV/Backend/CalDAV/CalDAVTasks.php b/app/Http/Controllers/DAV/Backend/CalDAV/CalDAVTasks.php index e1248680600..c67384bb364 100644 --- a/app/Http/Controllers/DAV/Backend/CalDAV/CalDAVTasks.php +++ b/app/Http/Controllers/DAV/Backend/CalDAV/CalDAVTasks.php @@ -49,6 +49,17 @@ public function getObjects($collectionId) ->get(); } + /** + * Returns the collection of deleted tasks. + * + * @param string|null $collectionId + * @return \Illuminate\Support\Collection + */ + public function getDeletedObjects($collectionId) + { + return collect(); + } + /** * Returns the contact for the specific uuid. * diff --git a/app/Http/Controllers/DAV/Backend/CardDAV/CardDAVBackend.php b/app/Http/Controllers/DAV/Backend/CardDAV/CardDAVBackend.php index ffcbbc9c32e..0a611cb4eed 100644 --- a/app/Http/Controllers/DAV/Backend/CardDAV/CardDAVBackend.php +++ b/app/Http/Controllers/DAV/Backend/CardDAV/CardDAVBackend.php @@ -17,6 +17,7 @@ use Sabre\CardDAV\Plugin as CardDAVPlugin; use Sabre\DAV\Sync\Plugin as DAVSyncPlugin; use App\Services\Contact\Contact\SetMeContact; +use App\Services\Contact\Contact\DestroyContact; use App\Http\Controllers\DAV\Backend\IDAVBackend; use App\Http\Controllers\DAV\Backend\SyncDAVBackend; use App\Http\Controllers\DAV\DAVACL\PrincipalBackend; @@ -267,6 +268,19 @@ public function getObjects($collectionId) ->get(); } + /** + * Returns the collection of deleted contacts. + * + * @param string|null $collectionId + * @return \Illuminate\Support\Collection + */ + public function getDeletedObjects($collectionId) + { + return $this->user->account->contacts($collectionId) + ->onlyTrashed() + ->get(); + } + /** * Returns all cards for a specific addressbook id. * @@ -393,6 +407,17 @@ public function updateCard($addressBookId, $cardUri, $cardData): ?string */ public function deleteCard($addressBookId, $cardUri) { + $contact = $this->getObject($addressBookId, $cardUri); + + if ($contact) { + DestroyContact::dispatch([ + 'account_id' => $contact->account_id, + 'contact_id' => $contact->id, + ]); + + return true; + } + return false; } diff --git a/app/Http/Controllers/DAV/Backend/SyncDAVBackend.php b/app/Http/Controllers/DAV/Backend/SyncDAVBackend.php index ac0faae6123..2916d0ae81d 100644 --- a/app/Http/Controllers/DAV/Backend/SyncDAVBackend.php +++ b/app/Http/Controllers/DAV/Backend/SyncDAVBackend.php @@ -175,6 +175,13 @@ public function getChanges($calendarId, $syncToken): ?array return is_null($timestamp) || $obj->created_at >= $timestamp; }); + $deleted = $this->getDeletedObjects($calendarId) + ->filter(function ($obj) use ($timestamp) { + $d = $obj->deleted_at; + + return is_null($timestamp) || + $obj->deleted_at >= $timestamp; + }); return [ 'syncToken' => $this->refreshSyncToken($calendarId)->id, @@ -186,7 +193,9 @@ public function getChanges($calendarId, $syncToken): ?array return $this->encodeUri($obj); })->values()->toArray(), - 'deleted' => [], + 'deleted' => $deleted->map(function ($obj) { + return $this->encodeUri($obj); + })->values()->toArray(), ]; } @@ -256,6 +265,14 @@ abstract public function getObjectUuid($collectionId, $uuid); */ abstract public function getObjects($collectionId); + /** + * Returns the collection of objects. + * + * @param string|null $collectionId + * @return \Illuminate\Support\Collection + */ + abstract public function getDeletedObjects($collectionId); + abstract public function getExtension(); /** diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php index 6216f56dd1f..977d4e7d33b 100644 --- a/app/Http/Controllers/SettingsController.php +++ b/app/Http/Controllers/SettingsController.php @@ -157,7 +157,7 @@ public function reset(Request $request) $user = $request->user(); $account = $user->account; - app(ResetAccount::class)->execute([ + ResetAccount::dispatch([ 'account_id' => $account->id, ]); diff --git a/app/Models/Account/Photo.php b/app/Models/Account/Photo.php index add8c53d54c..070ad1ac74f 100644 --- a/app/Models/Account/Photo.php +++ b/app/Models/Account/Photo.php @@ -87,4 +87,21 @@ public function dataUrl(): ?string return null; } } + + /** + * Delete the model from the database. + * + * @return bool|null + */ + public function delete() + { + try { + Storage::disk(config('filesystems.default')) + ->delete($this->new_filename); + } catch (FileNotFoundException $e) { + // continue + } + + return parent::delete(); + } } diff --git a/app/Models/Contact/Contact.php b/app/Models/Contact/Contact.php index 48aeae8065d..cbfdc77d733 100644 --- a/app/Models/Contact/Contact.php +++ b/app/Models/Contact/Contact.php @@ -25,7 +25,9 @@ use App\Models\Account\ActivityStatistic; use App\Models\Relationship\Relationship; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Prunable; use App\Models\ModelBindingHasher as Model; +use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Validation\ValidationException; use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Database\Eloquent\Relations\HasOne; @@ -42,7 +44,7 @@ */ class Contact extends Model { - use Searchable; + use Searchable, SoftDeletes, Prunable; /** @var array */ protected $dates = [ @@ -1179,10 +1181,12 @@ public function getAvatarURL() /** * Delete avatars files. * This does not touch avatar_location or avatar_file_name properties of the contact. + * + * @param bool $force */ - public function deleteAvatars() + public function deleteAvatars(bool $force = false) { - if (! $this->has_avatar || $this->avatar_location == 'external') { + if (! $force && (! $this->has_avatar || $this->avatar_location == 'external')) { return; } @@ -1564,4 +1568,26 @@ public function throwInactive() ]); } } + + /** + * Get the prunable model query. + * + * @return \Illuminate\Database\Eloquent\Builder + * @codeCoverageIgnore + */ + public function prunable() + { + return static::where('deleted_at', '<=', now()->subWeek()); + } + + /** + * Prepare the model for pruning. + * + * @return void + * @codeCoverageIgnore + */ + protected function pruning() + { + $this->deleteAvatars(true); + } } diff --git a/app/Models/Contact/Document.php b/app/Models/Contact/Document.php index d53ceb83f19..6493e328780 100644 --- a/app/Models/Contact/Document.php +++ b/app/Models/Contact/Document.php @@ -5,7 +5,9 @@ use App\Helpers\StorageHelper; use App\Models\Account\Account; use App\Models\ModelBinding as Model; +use Illuminate\Support\Facades\Storage; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Contracts\Filesystem\FileNotFoundException; class Document extends Model { @@ -65,4 +67,21 @@ public function getDownloadLink(): string return route('storage', ['file' => $this->new_filename]); } + + /** + * Delete the model from the database. + * + * @return bool|null + */ + public function delete() + { + try { + Storage::disk(config('filesystems.default')) + ->delete($this->new_filename); + } catch (FileNotFoundException $e) { + // continue + } + + return parent::delete(); + } } diff --git a/app/Services/Account/Settings/DestroyAllDocuments.php b/app/Services/Account/Settings/DestroyAllDocuments.php index 4ec92e6bd5b..6610fe9d207 100644 --- a/app/Services/Account/Settings/DestroyAllDocuments.php +++ b/app/Services/Account/Settings/DestroyAllDocuments.php @@ -4,8 +4,6 @@ use App\Services\BaseService; use App\Models\Contact\Document; -use Illuminate\Support\Facades\Storage; -use Illuminate\Contracts\Filesystem\FileNotFoundException; class DestroyAllDocuments extends BaseService { @@ -35,12 +33,6 @@ public function execute(array $data): bool ->get(); foreach ($documents as $document) { - try { - Storage::delete($document->new_filename); - } catch (FileNotFoundException $e) { - continue; - } - $document->delete(); } diff --git a/app/Services/Account/Settings/DestroyAllPhotos.php b/app/Services/Account/Settings/DestroyAllPhotos.php index 3937d795045..a1a21db9e30 100644 --- a/app/Services/Account/Settings/DestroyAllPhotos.php +++ b/app/Services/Account/Settings/DestroyAllPhotos.php @@ -4,8 +4,6 @@ use App\Models\Account\Photo; use App\Services\BaseService; -use Illuminate\Support\Facades\Storage; -use Illuminate\Contracts\Filesystem\FileNotFoundException; class DestroyAllPhotos extends BaseService { @@ -35,12 +33,6 @@ public function execute(array $data): bool ->get(); foreach ($photos as $photo) { - try { - Storage::delete($photo->new_filename); - } catch (FileNotFoundException $e) { - continue; - } - $photo->delete(); } diff --git a/app/Services/Account/Settings/ResetAccount.php b/app/Services/Account/Settings/ResetAccount.php index 25e14bf9302..b0dc333dd54 100644 --- a/app/Services/Account/Settings/ResetAccount.php +++ b/app/Services/Account/Settings/ResetAccount.php @@ -4,9 +4,14 @@ use App\Services\BaseService; use App\Models\Account\Account; +use App\Services\QueuableService; +use App\Services\DispatchableService; +use App\Services\Contact\Contact\DestroyContact; -class ResetAccount extends BaseService +class ResetAccount extends BaseService implements QueuableService { + use DispatchableService; + /** * Get the validation rules that apply to the service. * @@ -25,7 +30,7 @@ public function rules() * @param array $data * @return void */ - public function execute(array $data): void + public function handle(array $data): void { $this->validate($data); @@ -165,7 +170,11 @@ private function destroyContacts(Account $account) { $contacts = $account->contacts; foreach ($contacts as $contact) { - $contact->delete(); + DestroyContact::dispatchSync([ + 'account_id' => $contact->account_id, + 'contact_id' => $contact->id, + 'force_delete' => true, + ]); } } } diff --git a/app/Services/Contact/Contact/DestroyContact.php b/app/Services/Contact/Contact/DestroyContact.php index d1508c81fa0..6438d61c649 100644 --- a/app/Services/Contact/Contact/DestroyContact.php +++ b/app/Services/Contact/Contact/DestroyContact.php @@ -23,6 +23,7 @@ public function rules() return [ 'account_id' => 'required|integer|exists:accounts,id', 'contact_id' => 'required|integer|exists:contacts,id', + 'force_delete' => 'nullable|boolean', ]; } @@ -44,7 +45,12 @@ public function handle(array $data): void $this->destroyRelationships($data, $contact); $contact->deleteAvatars(); - $contact->delete(); + + if ($this->valueOrFalse($data, 'force_delete') === true) { + $contact->forceDelete(); + } else { + $contact->delete(); + } } /** diff --git a/app/Services/Contact/Relationship/DestroyRelationship.php b/app/Services/Contact/Relationship/DestroyRelationship.php index 7ab347d299c..f113fd2bf88 100644 --- a/app/Services/Contact/Relationship/DestroyRelationship.php +++ b/app/Services/Contact/Relationship/DestroyRelationship.php @@ -6,6 +6,7 @@ use App\Models\Contact\Contact; use App\Models\Relationship\Relationship; use Illuminate\Database\Eloquent\Builder; +use App\Services\Contact\Contact\DestroyContact; class DestroyRelationship extends BaseService { @@ -79,7 +80,10 @@ private function deletePartialContact(Contact $contact) ->count(); if ($otherRelations == 0) { - $contact->delete(); + DestroyContact::dispatch([ + 'account_id' => $contact->account_id, + 'contact_id' => $contact->id, + ]); } } } diff --git a/app/Services/DavClient/Utils/AddressBookSynchronizer.php b/app/Services/DavClient/Utils/AddressBookSynchronizer.php index 01616490134..9dbb86ee291 100644 --- a/app/Services/DavClient/Utils/AddressBookSynchronizer.php +++ b/app/Services/DavClient/Utils/AddressBookSynchronizer.php @@ -119,11 +119,11 @@ private function getDistantChanges(): Collection return $this->filterDistantContacts($contact, $href); }) ->map(function ($contact, $href): ContactDto { - return new ContactDto($href, Arr::get($contact, '200.{DAV:}getetag')); + return new ContactDto($href, Arr::get($contact, 'properties.200.{DAV:}getetag')); }); $deleted = $etags->filter(function ($contact): bool { - return isset($contact['404']); + return is_array($contact) && $contact['status'] === '404'; }) ->map(function ($contact, $href): ContactDto { return new ContactDeleteDto($href); @@ -142,14 +142,14 @@ private function getDistantChanges(): Collection private function filterDistantContacts($contact, $href): bool { // only return vcards - if (! is_array($contact) || ! Str::contains(Arr::get($contact, '200.{DAV:}getcontenttype'), 'text/vcard')) { + if (! is_array($contact) || ! Str::contains(Arr::get($contact, 'properties.200.{DAV:}getcontenttype'), 'text/vcard')) { return false; } // only new contact or contact with etag that match $card = $this->backend()->getCard($this->sync->addressBookName(), $href); - return $card === false || $card['etag'] !== Arr::get($contact, '200.{DAV:}getetag'); + return $card === false || $card['etag'] !== Arr::get($contact, 'properties.200.{DAV:}getetag'); } /** @@ -228,13 +228,13 @@ private function getAllContactsEtag(): Collection $data = collect($data); $updated = $data->filter(function ($contact): bool { - return isset($contact[200]); + return is_array($contact) && $contact['status'] === '200'; }) ->map(function ($contact, $href): ContactDto { - return new ContactDto($href, Arr::get($contact, '200.{DAV:}getetag')); + return new ContactDto($href, Arr::get($contact, 'properties.200.{DAV:}getetag')); }); $deleted = $data->filter(function ($contact): bool { - return isset($contact[404]); + return is_array($contact) && $contact['status'] === '404'; }) ->map(function ($contact, $href): ContactDto { return new ContactDeleteDto($href); diff --git a/app/Services/DavClient/Utils/Dav/DavClient.php b/app/Services/DavClient/Utils/Dav/DavClient.php index 45fbaf6d7c0..14061b588b8 100644 --- a/app/Services/DavClient/Utils/Dav/DavClient.php +++ b/app/Services/DavClient/Utils/Dav/DavClient.php @@ -192,11 +192,11 @@ public function propFind($properties, int $depth = 0, array $options = [], strin reset($result); $result = current($result); - return Arr::get($result, 200, []); + return Arr::get($result, 'properties.200', []); } return array_map(function ($statusList) { - return Arr::get($statusList, 200, []); + return Arr::get($statusList, 'properties.200', []); }, $result); } @@ -454,7 +454,7 @@ public function propPatch(array $properties, string $url = ''): bool $errorProperties = []; foreach ($result as $statusList) { - foreach ($statusList as $status => $properties) { + foreach ($statusList['properties'] as $status => $properties) { if ($status >= 400) { foreach ($properties as $propName => $propValue) { $errorProperties[] = $propName.' ('.$status.')'; @@ -527,14 +527,17 @@ public function request(string $method, string $url = '', $body = null, array $h * * [ * 'url/to/resource' => [ - * '200' => [ - * '{DAV:}property1' => 'value1', - * '{DAV:}property2' => 'value2', - * ], - * '404' => [ - * '{DAV:}property1' => null, - * '{DAV:}property2' => null, + * 'properties' => [ + * '200' => [ + * '{DAV:}property1' => 'value1', + * '{DAV:}property2' => 'value2', + * ], + * '404' => [ + * '{DAV:}property1' => null, + * '{DAV:}property2' => null, + * ], * ], + * 'status' => 200, * ], * 'url/to/resource2' => [ * .. etc .. @@ -554,7 +557,10 @@ private static function parseMultiStatus(string $body): array $result = []; foreach ($multistatus->getResponses() as $response) { - $result[$response->getHref()] = $response->getResponseProperties(); + $result[$response->getHref()] = [ + 'properties' => $response->getResponseProperties(), + 'status' => $response->getHttpStatus() ?? '200', + ]; } $synctoken = $multistatus->getSyncToken(); diff --git a/database/migrations/2019_12_17_024553_add_foreign_keys.php b/database/migrations/2019_12_17_024553_add_foreign_keys.php index 991023a4f06..77565bec1ba 100644 --- a/database/migrations/2019_12_17_024553_add_foreign_keys.php +++ b/database/migrations/2019_12_17_024553_add_foreign_keys.php @@ -634,7 +634,7 @@ private function cleanContactTable() try { $this->accountExistOrFail($contact->account_id); } catch (ModelNotFoundException $e) { - $contact->delete(); + $contact->forceDelete(); continue; } } diff --git a/database/migrations/2017_02_10_215705_remove_deleted_at_from_contact.php b/database/migrations/2022_01_02_222042_contact_soft_delete.php similarity index 61% rename from database/migrations/2017_02_10_215705_remove_deleted_at_from_contact.php rename to database/migrations/2022_01_02_222042_contact_soft_delete.php index d244989b8a2..1abeb73a069 100644 --- a/database/migrations/2017_02_10_215705_remove_deleted_at_from_contact.php +++ b/database/migrations/2022_01_02_222042_contact_soft_delete.php @@ -4,7 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; -class RemoveDeletedAtFromContact extends Migration +class ContactSoftDelete extends Migration { /** * Run the migrations. @@ -13,11 +13,11 @@ class RemoveDeletedAtFromContact extends Migration */ public function up() { - Schema::table('contacts', function (Blueprint $table) { - $table->dropColumn( - 'deleted_at' - ); - }); + if (! Schema::hasColumn('contacts', 'deleted_at')) { + Schema::table('contacts', function (Blueprint $table) { + $table->softDeletes(); + }); + } } /** @@ -28,7 +28,7 @@ public function up() public function down() { Schema::table('contacts', function (Blueprint $table) { - $table->softDeletes(); + $table->dropSoftDeletes(); }); } } diff --git a/tests/Api/Contact/ApiContactControllerTest.php b/tests/Api/Contact/ApiContactControllerTest.php index 77cbdad7166..86f4a7f220f 100644 --- a/tests/Api/Contact/ApiContactControllerTest.php +++ b/tests/Api/Contact/ApiContactControllerTest.php @@ -1381,6 +1381,7 @@ public function it_deletes_a_contact() $this->assertDatabaseMissing('contacts', [ 'account_id' => $user->account_id, 'id' => $contact->id, + 'deleted_at' => null, ]); } diff --git a/tests/Api/DAV/CardDAVTest.php b/tests/Api/DAV/CardDAVTest.php index d4c8c072601..01362b8fc42 100644 --- a/tests/Api/DAV/CardDAVTest.php +++ b/tests/Api/DAV/CardDAVTest.php @@ -393,6 +393,63 @@ public function test_carddav_sync_collection_init() http://sabre.io/ns/sync/{$token->id} +", false); + } + + public function test_carddav_sync_collection_deleted_contact() + { + Carbon::setTestNow(Carbon::create(2019, 1, 1, 9, 0, 0)); + + $user = $this->signin(); + $contact = factory(Contact::class)->create([ + 'account_id' => $user->account_id, + 'deleted_at' => Carbon::create(2019, 3, 1, 9, 0, 0), + ]); + + Carbon::setTestNow(Carbon::create(2019, 2, 1, 9, 0, 0)); + $token = factory(SyncToken::class)->create([ + 'account_id' => $user->account_id, + 'user_id' => $user->id, + 'name' => 'contacts', + 'timestamp' => now(), + ]); + + Carbon::setTestNow(Carbon::create(2019, 4, 1, 9, 0, 0)); + + $response = $this->call('REPORT', "/dav/addressbooks/{$user->email}/contacts/", [], [], [], + [ + 'content-type' => 'application/xml; charset=utf-8', + ], + " + http://sabre.io/ns/sync/{$token->id} + 1 + + + + " + ); + + $response->assertStatus(207); + + $token = SyncToken::where([ + 'account_id' => $user->account_id, + 'user_id' => $user->id, + 'name' => 'contacts', + ]) + ->orderBy('created_at') + ->get() + ->last(); + + $response->assertSee(" + + HTTP/1.1 404 Not Found + /dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf + + + HTTP/1.1 418 I'm a teapot + + + http://sabre.io/ns/sync/{$token->id} ", false); } } diff --git a/tests/Api/DAV/VCardContactTest.php b/tests/Api/DAV/VCardContactTest.php index 39796da5c39..01f3f9892d4 100644 --- a/tests/Api/DAV/VCardContactTest.php +++ b/tests/Api/DAV/VCardContactTest.php @@ -467,4 +467,28 @@ public function test_carddav_contacts_report_multiget() ''. '', false); } + + /** + * @group dav + * @test + */ + public function carddav_delete_one_contact() + { + $user = $this->signin(); + $contact = factory(Contact::class)->create([ + 'account_id' => $user->account_id, + ]); + + $response = $this->call('DELETE', "/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf"); + + $response->assertStatus(204); + $response->assertHeader('X-Sabre-Version'); + $response->assertHeaderMissing('ETag'); + + $this->assertDatabaseMissing('contacts', [ + 'account_id' => $user->account_id, + 'id' => $contact->id, + 'deleted_at' => null, + ]); + } } diff --git a/tests/Unit/Services/Account/Settings/DestroyAccountTest.php b/tests/Unit/Services/Account/Settings/DestroyAccountTest.php index b820fae60e1..b56ef0fca24 100644 --- a/tests/Unit/Services/Account/Settings/DestroyAccountTest.php +++ b/tests/Unit/Services/Account/Settings/DestroyAccountTest.php @@ -29,6 +29,7 @@ public function it_destroys_an_account() $this->assertDatabaseMissing('contacts', [ 'account_id' => $user->account_id, + 'deleted_at' => null, ]); $this->assertDatabaseMissing('accounts', [ 'id' => $user->account_id, diff --git a/tests/Unit/Services/Account/Settings/ResetAccountTest.php b/tests/Unit/Services/Account/Settings/ResetAccountTest.php index ba2d40917bb..6da12a0bb9a 100644 --- a/tests/Unit/Services/Account/Settings/ResetAccountTest.php +++ b/tests/Unit/Services/Account/Settings/ResetAccountTest.php @@ -45,10 +45,11 @@ public function it_resets_an_account() 'account_id' => $user->account_id, ]; - app(ResetAccount::class)->execute($request); + app(ResetAccount::class)->handle($request); $this->assertDatabaseMissing('contacts', [ 'account_id' => $user->account_id, + 'deleted_at' => null, ]); $this->assertDatabaseMissing('activities', [ 'account_id' => $user->account_id, @@ -61,6 +62,6 @@ public function it_fails_if_wrong_parameters_are_given() $request = []; $this->expectException(ValidationException::class); - app(ResetAccount::class)->execute($request); + app(ResetAccount::class)->handle($request); } } diff --git a/tests/Unit/Services/Contact/Contact/DestroyContactTest.php b/tests/Unit/Services/Contact/Contact/DestroyContactTest.php index 8e020f5f087..86a5908f3e1 100644 --- a/tests/Unit/Services/Contact/Contact/DestroyContactTest.php +++ b/tests/Unit/Services/Contact/Contact/DestroyContactTest.php @@ -28,6 +28,7 @@ public function it_destroys_a_contact() $this->assertDatabaseMissing('contacts', [ 'id' => $contact->id, + 'deleted_at' => null, ]); } diff --git a/tests/Unit/Services/Contact/Relationship/DestroyRelationshipTest.php b/tests/Unit/Services/Contact/Relationship/DestroyRelationshipTest.php index dcf095edd32..55ca0a4e7e1 100644 --- a/tests/Unit/Services/Contact/Relationship/DestroyRelationshipTest.php +++ b/tests/Unit/Services/Contact/Relationship/DestroyRelationshipTest.php @@ -151,6 +151,7 @@ public function it_destroys_a_relationship_and_reverse_and_partial_contact() ]); $this->assertDatabaseMissing('contacts', [ 'id' => $contactB->id, + 'deleted_at' => null, ]); } diff --git a/tests/Unit/Services/DavClient/Utils/AddressBookSynchronizerTest.php b/tests/Unit/Services/DavClient/Utils/AddressBookSynchronizerTest.php index 38f7a73b693..ca0c468ee32 100644 --- a/tests/Unit/Services/DavClient/Utils/AddressBookSynchronizerTest.php +++ b/tests/Unit/Services/DavClient/Utils/AddressBookSynchronizerTest.php @@ -164,13 +164,11 @@ public function it_sync_changes_deleted_contact_batched() $tester->getSynctoken('"token"') ->addResponse('https://test/dav/addressbooks/user@test.com/contacts/', Http::response(DavTester::multistatusHeader(). ''. + 'HTTP/1.1 404 Not Found'. 'https://test/dav/addressbooks/user@test.com/contacts/uuid'. ''. - ''. - ''. - 'text/vcard'. - ''. - 'HTTP/1.1 404 Not Found'. + ''. + 'HTTP/1.1 418 I\'m a teapot'. ''. ''. 'token'. @@ -310,7 +308,7 @@ public function it_forcesync_changes_added_local_contact_batched() } /** @test */ - public function it_forcesync_changes_removed_contact_batched() + public function it_forcesync_changes_deleted_contact_batched() { Bus::fake(); @@ -320,12 +318,11 @@ public function it_forcesync_changes_removed_contact_batched() ->fake(); $tester->addResponse('https://test/dav/addressbooks/user@test.com/contacts/', Http::response(DavTester::multistatusHeader(). ''. + 'HTTP/1.1 404 Not Found'. 'https://test/dav/uuid1'. ''. - ''. - ''. - ''. - 'HTTP/1.1 404 Not Found'. + ''. + 'HTTP/1.1 418 I\'m a teapot'. ''. ''. ''), ''."\n". diff --git a/tests/Unit/Services/DavClient/Utils/Dav/DavClientTest.php b/tests/Unit/Services/DavClient/Utils/Dav/DavClientTest.php index 76235630509..590acee3254 100644 --- a/tests/Unit/Services/DavClient/Utils/Dav/DavClientTest.php +++ b/tests/Unit/Services/DavClient/Utils/Dav/DavClientTest.php @@ -254,10 +254,13 @@ public function it_sync_collection() $tester->assert(); $this->assertEquals([ 'href' => [ - 200 => [ - '{DAV:}getetag' => '"00001-abcd1"', - '{DAV:}test' => 'value', + 'properties' => [ + 200 => [ + '{DAV:}getetag' => '"00001-abcd1"', + '{DAV:}test' => 'value', + ], ], + 'status' => '200', ], 'synctoken' => '"00001-abcd1"', ], $result); @@ -296,10 +299,13 @@ public function it_sync_collection_with_synctoken() $tester->assert(); $this->assertEquals([ 'href' => [ - 200 => [ - '{DAV:}getetag' => '"00001-abcd1"', - '{DAV:}test' => 'value', + 'properties' => [ + 200 => [ + '{DAV:}getetag' => '"00001-abcd1"', + '{DAV:}test' => 'value', + ], ], + 'status' => '200', ], 'synctoken' => '"00001-abcd1"', ], $result); @@ -335,10 +341,13 @@ public function it_run_addressbook_multiget_report() $this->assertEquals([ 'href' => [ - 200 => [ - '{DAV:}getetag' => '"00001-abcd1"', - '{DAV:}test' => 'value', + 'properties' => [ + 200 => [ + '{DAV:}getetag' => '"00001-abcd1"', + '{DAV:}test' => 'value', + ], ], + 'status' => '200', ], ], $result); @@ -375,10 +384,13 @@ public function it_run_addressbook_query_report() $tester->assert(); $this->assertEquals([ 'href' => [ - 200 => [ - '{DAV:}getetag' => '"00001-abcd1"', - '{DAV:}test' => 'value', + 'properties' => [ + 200 => [ + '{DAV:}getetag' => '"00001-abcd1"', + '{DAV:}test' => 'value', + ], ], + 'status' => '200', ], ], $result); }