diff --git a/src/app/Console/Commands/User/ResyncCommand.php b/src/app/Console/Commands/User/ResyncCommand.php --- a/src/app/Console/Commands/User/ResyncCommand.php +++ b/src/app/Console/Commands/User/ResyncCommand.php @@ -2,7 +2,10 @@ namespace App\Console\Commands\User; +use App\Backends\IMAP; +use App\Backends\LDAP; use App\Console\Command; +use App\Domain; use App\User; class ResyncCommand extends Command @@ -97,9 +100,37 @@ continue; } + $job = \App\Jobs\User\UpdateJob::class; + + // Make sure the LDAP entry exists, fix that + if ($with_ldap && $user->isLdapReady()) { + // Check (and fix) the custom domain state + $domain = $user->domain(); + if (!$domain->isPublic() && !LDAP::getDomain($domain->namespace)) { + $domain->status &= ~Domain::STATUS_LDAP_READY; + $domain->save(); + \App\Jobs\Domain\CreateJob::dispatch($domain->id); + } + + if (!LDAP::getUser($user->email)) { + $user->status &= ~User::STATUS_LDAP_READY; + $job = \App\Jobs\User\CreateJob::class; + } + } + + // Make sure the IMAP mailbox exists + if ($user->isImapReady()) { + if (!IMAP::verifyAccount($user->email)) { + $user->status &= ~User::STATUS_IMAP_READY; + $job = \App\Jobs\User\CreateJob::class; + } + } + + $user->update(); + // We push the update only if a specific user is requested, // We don't want to flood the database/backend with an update of all users - \App\Jobs\User\UpdateJob::dispatch($user->id); + $job::dispatch($user->id); $this->info("{$user->email}: pushed"); } else { diff --git a/src/tests/Feature/Console/User/ResyncTest.php b/src/tests/Feature/Console/User/ResyncTest.php --- a/src/tests/Feature/Console/User/ResyncTest.php +++ b/src/tests/Feature/Console/User/ResyncTest.php @@ -2,6 +2,7 @@ namespace Tests\Feature\Console\User; +use App\Domain; use App\User; use Illuminate\Support\Facades\Queue; use Tests\TestCase; @@ -16,6 +17,7 @@ parent::setUp(); $this->deleteTestUser('user@force-delete.com'); + $this->deleteTestDomain('force-delete.com'); } /** @@ -24,14 +26,15 @@ public function tearDown(): void { $this->deleteTestUser('user@force-delete.com'); + $this->deleteTestDomain('force-delete.com'); parent::tearDown(); } /** - * Test the command + * Test the command (deleted and non-existing users) */ - public function testHandle(): void + public function testHandleDeleted(): void { // Non-existing user $code = \Artisan::call("user:resync unknown"); @@ -58,7 +61,7 @@ Queue::assertNothingPushed(); - // Test success + // Test success (deleted user) $code = \Artisan::call("user:resync {$user->email}"); $output = trim(\Artisan::output()); @@ -99,7 +102,50 @@ $this->assertSame(0, $code); $this->assertSame("{$user->email}: pushed", $output); + } + + /** + * Test the command (existing users) + * + * @group ldap + * @group imap + */ + public function testHandleExisting(): void + { + $domain = $this->getTestDomain('force-delete.com', [ + 'status' => Domain::STATUS_LDAP_READY | Domain::STATUS_ACTIVE, + 'type' => Domain::TYPE_EXTERNAL, + ]); + + $user = $this->getTestUser('user@force-delete.com', [ + 'status' => User::STATUS_LDAP_READY | User::STATUS_IMAP_READY | User::STATUS_ACTIVE, + ]); + + Queue::fake(); + + // Test a user (and custom domain) that both aren't in ldap (despite their status) + $code = \Artisan::call("user:resync {$user->email}"); + $output = trim(\Artisan::output()); + + $this->assertSame(0, $code); + $this->assertSame("{$user->email}: pushed", $output); + $user->refresh(); + $domain->refresh(); + $this->assertFalse($user->isLdapReady()); + $this->assertFalse($user->isImapReady()); + $this->assertFalse($domain->isLdapReady()); + + Queue::assertPushed(\App\Jobs\User\CreateJob::class, 1); + Queue::assertPushed(\App\Jobs\User\CreateJob::class, function ($job) use ($user) { + $job_user_id = TestCase::getObjectProperty($job, 'userId'); + return $job_user_id === $user->id; + }); + Queue::assertPushed(\App\Jobs\Domain\CreateJob::class, 1); + Queue::assertPushed(\App\Jobs\Domain\CreateJob::class, function ($job) use ($domain) { + $job_domain_id = TestCase::getObjectProperty($job, 'domainId'); + return $job_domain_id === $domain->id; + }); - // TODO: Test other cases (non-deleted users) + // TODO: Test other cases } }