Page MenuHomePhorge

D925.1775683852.diff
No OneTemporary

Authored By
Unknown
Size
35 KB
Referenced Files
None
Subscribers
None

D925.1775683852.diff

diff --git a/src/app/Backends/IMAP.php b/src/app/Backends/IMAP.php
new file mode 100644
--- /dev/null
+++ b/src/app/Backends/IMAP.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace App\Backends;
+
+use App\Domain;
+use App\User;
+
+class IMAP
+{
+ /**
+ * Check if an account is set up
+ *
+ * @param string $username User login (email address)
+ *
+ * @return bool
+ */
+ public static function verifyAccount(string $username): bool
+ {
+ // TODO
+ return true;
+ }
+}
diff --git a/src/app/Domain.php b/src/app/Domain.php
--- a/src/app/Domain.php
+++ b/src/app/Domain.php
@@ -8,14 +8,18 @@
{
// we've simply never heard of this domain
public const STATUS_NEW = 1 << 0;
- // it's been activated -- mutually exclusive with new?
+ // it's been activated
public const STATUS_ACTIVE = 1 << 1;
- // ownership of the domain has been confirmed -- mutually exclusive with new?
- public const STATUS_CONFIRMED = 1 << 2;
// domain has been suspended.
- public const STATUS_SUSPENDED = 1 << 3;
- // domain has been deleted -- can not be active any more.
- public const STATUS_DELETED = 1 << 4;
+ public const STATUS_SUSPENDED = 1 << 2;
+ // domain has been deleted
+ public const STATUS_DELETED = 1 << 3;
+ // ownership of the domain has been confirmed
+ public const STATUS_CONFIRMED = 1 << 4;
+ // domain has been verified that it exists in DNS
+ public const STATUS_VERIFIED = 1 << 5;
+ // domain has been created in LDAP
+ public const STATUS_LDAP_READY = 1 << 6;
// open for public registration
public const TYPE_PUBLIC = 1 << 0;
@@ -33,10 +37,6 @@
'type'
];
- //protected $guarded = [
- // "status"
- //];
-
public function entitlement()
{
return $this->morphOne('App\Entitlement', 'entitleable');
@@ -124,6 +124,16 @@
return $this->type & self::TYPE_PUBLIC;
}
+ /**
+ * Returns whether this domain is registered in LDAP.
+ *
+ * @return bool
+ */
+ public function isLdapReady(): bool
+ {
+ return $this->status & self::STATUS_LDAP_READY;
+ }
+
/**
* Returns whether this domain is suspended.
*
@@ -134,6 +144,17 @@
return $this->status & self::STATUS_SUSPENDED;
}
+ /**
+ * Returns whether this (external) domain has been verified
+ * to exist in DNS.
+ *
+ * @return bool
+ */
+ public function isVerified(): bool
+ {
+ return $this->status & self::STATUS_VERIFIED;
+ }
+
/**
* Domain status mutator
*
@@ -149,6 +170,8 @@
self::STATUS_CONFIRMED,
self::STATUS_SUSPENDED,
self::STATUS_DELETED,
+ self::STATUS_LDAP_READY,
+ self::STATUS_VERIFIED,
];
foreach ($allowed_values as $value) {
@@ -164,4 +187,23 @@
$this->attributes['status'] = $new_status;
}
+
+ /**
+ * Verify if a domain exists in DNS
+ *
+ * @param string $domain Domain name
+ *
+ * @return bool True if registered, False otherwise
+ * @throws \Exception
+ */
+ public static function verifyDomain(string $domain): bool
+ {
+ $record = dns_get_record($domain, DNS_SOA);
+
+ if ($record === false) {
+ throw new \Exception("Failed to get DNS record for $domain");
+ }
+
+ return !empty($record);
+ }
}
diff --git a/src/app/Http/Controllers/API/UsersController.php b/src/app/Http/Controllers/API/UsersController.php
--- a/src/app/Http/Controllers/API/UsersController.php
+++ b/src/app/Http/Controllers/API/UsersController.php
@@ -3,6 +3,7 @@
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
+use App\Domain;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@@ -73,7 +74,12 @@
*/
public function info()
{
- return response()->json($this->guard()->user());
+ $user = $this->guard()->user();
+ $response = $user->toArray();
+
+ $response['statusInfo'] = self::statusInfo($user);
+
+ return response()->json($response);
}
/**
@@ -170,6 +176,59 @@
return \App\User::find($id);
}
+ /**
+ * User status (extended) information
+ *
+ * @param \App\User $user User object
+ *
+ * @return array Status information
+ */
+ public static function statusInfo(User $user): array
+ {
+ $status = 'new';
+ $process = [];
+ $steps = [
+ 'user-new' => true,
+ 'user-ldap-ready' => 'isLdapReady',
+ 'user-imap-ready' => 'isImapReady',
+ ];
+
+ if ($user->isDeleted()) {
+ $status = 'deleted';
+ } elseif ($user->isSuspended()) {
+ $status = 'suspended';
+ } elseif ($user->isActive()) {
+ $status = 'active';
+ }
+
+ list ($local, $domain) = explode('@', $user->email);
+ $domain = Domain::where('namespace', $domain)->first();
+
+ // If that is not a public domain, add domain specific steps
+ if (!$domain->isPublic()) {
+ $steps['domain-new'] = true;
+ $steps['domain-ldap-ready'] = 'isLdapReady';
+ $steps['domain-verified'] = 'isVerified';
+ $steps['domain-confirmed'] = 'isConfirmed';
+ }
+
+ // Create a process check list
+ foreach ($steps as $step_name => $func) {
+ $object = strpos($step_name, 'user-') === 0 ? $user : $domain;
+
+ $process[] = [
+ 'label' => $step_name,
+ 'title' => __("app.process-{$step_name}"),
+ 'state' => is_bool($func) ? $func : $object->{$func}(),
+ ];
+ }
+
+ return [
+ 'process' => $process,
+ 'status' => $status,
+ ];
+ }
+
/**
* Get the guard to be used during authentication.
*
diff --git a/src/app/Jobs/ProcessDomainCreate.php b/src/app/Jobs/ProcessDomainCreate.php
--- a/src/app/Jobs/ProcessDomainCreate.php
+++ b/src/app/Jobs/ProcessDomainCreate.php
@@ -43,6 +43,11 @@
*/
public function handle()
{
- LDAP::createDomain($this->domain);
+ if (!$this->domain->isLdapReady()) {
+ LDAP::createDomain($this->domain);
+
+ $this->domain->status |= Domain::STATUS_LDAP_READY;
+ $this->domain->save();
+ }
}
}
diff --git a/src/app/Jobs/ProcessDomainCreate.php b/src/app/Jobs/ProcessDomainVerify.php
copy from src/app/Jobs/ProcessDomainCreate.php
copy to src/app/Jobs/ProcessDomainVerify.php
--- a/src/app/Jobs/ProcessDomainCreate.php
+++ b/src/app/Jobs/ProcessDomainVerify.php
@@ -2,15 +2,14 @@
namespace App\Jobs;
-use App\Backends\LDAP;
use App\Domain;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
-use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
-class ProcessDomainCreate implements ShouldQueue
+class ProcessDomainVerify implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
@@ -43,6 +42,15 @@
*/
public function handle()
{
- LDAP::createDomain($this->domain);
+ if (!$this->domain->isVerified()) {
+ if (Domain::verifyDomain($this->domain->namespace)) {
+ $this->domain->status |= Domain::STATUS_VERIFIED;
+ $this->domain->save();
+ }
+
+ // TODO: What should happen if the domain is not registered yet?
+ // Should we start a new job with some specified delay?
+ // Or we just give the user a button to start verification again?
+ }
}
}
diff --git a/src/app/Jobs/ProcessUserCreate.php b/src/app/Jobs/ProcessUserCreate.php
--- a/src/app/Jobs/ProcessUserCreate.php
+++ b/src/app/Jobs/ProcessUserCreate.php
@@ -44,6 +44,11 @@
*/
public function handle()
{
- LDAP::createUser($this->user);
+ if (!$this->user->isLdapReady()) {
+ LDAP::createUser($this->user);
+
+ $this->user->status |= User::STATUS_LDAP_READY;
+ $this->user->save();
+ }
}
}
diff --git a/src/app/Jobs/ProcessUserCreate.php b/src/app/Jobs/ProcessUserVerify.php
copy from src/app/Jobs/ProcessUserCreate.php
copy to src/app/Jobs/ProcessUserVerify.php
--- a/src/app/Jobs/ProcessUserCreate.php
+++ b/src/app/Jobs/ProcessUserVerify.php
@@ -2,7 +2,6 @@
namespace App\Jobs;
-use App\Backends\LDAP;
use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
@@ -10,7 +9,7 @@
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
-class ProcessUserCreate implements ShouldQueue
+class ProcessUserVerify implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
@@ -44,6 +43,12 @@
*/
public function handle()
{
- LDAP::createUser($this->user);
+ if (!$this->user->isImapReady()) {
+ if (IMAP::verifyAccount($this->user->email)) {
+ $this->user->status |= User::STATUS_IMAP_READY;
+ $this->user->status |= User::STATUS_ACTIVE;
+ $this->user->save();
+ }
+ }
}
}
diff --git a/src/app/Observers/DomainObserver.php b/src/app/Observers/DomainObserver.php
--- a/src/app/Observers/DomainObserver.php
+++ b/src/app/Observers/DomainObserver.php
@@ -22,6 +22,8 @@
break;
}
}
+
+ $domain->status |= Domain::STATUS_NEW;
}
/**
@@ -33,7 +35,12 @@
*/
public function created(Domain $domain)
{
- \App\Jobs\ProcessDomainCreate::dispatch($domain);
+ // Create domain record in LDAP, then check if it exists in DNS
+ $chain = [
+ new \App\Jobs\ProcessDomainVerify($domain),
+ ];
+
+ \App\Jobs\ProcessDomainCreate::withChain($chain)->dispatch($domain);
}
/**
diff --git a/src/app/Observers/UserObserver.php b/src/app/Observers/UserObserver.php
--- a/src/app/Observers/UserObserver.php
+++ b/src/app/Observers/UserObserver.php
@@ -24,6 +24,9 @@
break;
}
}
+
+ $user->status |= User::STATUS_NEW;
+
// can't dispatch job here because it'll fail serialization
}
@@ -54,7 +57,12 @@
$user->wallets()->create();
- \App\Jobs\ProcessUserCreate::dispatch($user);
+ // Create user record in LDAP, then check if the account is created in IMAP
+ $chain = [
+ new \App\Jobs\ProcessUserVerify($user),
+ ];
+
+ \App\Jobs\ProcessUserCreate::withChain($chain)->dispatch($user);
}
/**
diff --git a/src/app/User.php b/src/app/User.php
--- a/src/app/User.php
+++ b/src/app/User.php
@@ -18,6 +18,20 @@
use NullableFields;
use UserSettingsTrait;
+ // a new user, default on creation
+ public const STATUS_NEW = 1 << 0;
+ // it's been activated
+ public const STATUS_ACTIVE = 1 << 1;
+ // user has been suspended
+ public const STATUS_SUSPENDED = 1 << 2;
+ // user has been deleted
+ public const STATUS_DELETED = 1 << 3;
+ // user has been created in LDAP
+ public const STATUS_LDAP_READY = 1 << 4;
+ // user mailbox has been created in IMAP
+ public const STATUS_IMAP_READY = 1 << 5;
+
+
// change the default primary key type
public $incrementing = false;
protected $keyType = 'bigint';
@@ -28,7 +42,11 @@
* @var array
*/
protected $fillable = [
- 'name', 'email', 'password', 'password_ldap'
+ 'name',
+ 'email',
+ 'password',
+ 'password_ldap',
+ 'status'
];
/**
@@ -37,7 +55,9 @@
* @var array
*/
protected $hidden = [
- 'password', 'password_ldap', 'remember_token',
+ 'password',
+ 'password_ldap',
+ 'remember_token',
];
protected $nullable = [
@@ -150,6 +170,82 @@
return $user;
}
+ public function getJWTIdentifier()
+ {
+ return $this->getKey();
+ }
+
+ public function getJWTCustomClaims()
+ {
+ return [];
+ }
+
+ /**
+ * Returns whether this domain is active.
+ *
+ * @return bool
+ */
+ public function isActive(): bool
+ {
+ return $this->status & self::STATUS_ACTIVE;
+ }
+
+ /**
+ * Returns whether this domain is deleted.
+ *
+ * @return bool
+ */
+ public function isDeleted(): bool
+ {
+ return $this->status & self::STATUS_DELETED;
+ }
+
+ /**
+ * Returns whether this (external) domain has been verified
+ * to exist in DNS.
+ *
+ * @return bool
+ */
+ public function isImapReady(): bool
+ {
+ return $this->status & self::STATUS_IMAP_READY;
+ }
+
+ /**
+ * Returns whether this user is registered in LDAP.
+ *
+ * @return bool
+ */
+ public function isLdapReady(): bool
+ {
+ return $this->status & self::STATUS_LDAP_READY;
+ }
+
+ /**
+ * Returns whether this user is new.
+ *
+ * @return bool
+ */
+ public function isNew(): bool
+ {
+ return $this->status & self::STATUS_NEW;
+ }
+
+ /**
+ * Returns whether this domain is suspended.
+ *
+ * @return bool
+ */
+ public function isSuspended(): bool
+ {
+ return $this->status & self::STATUS_SUSPENDED;
+ }
+
+ /**
+ * Any (additional) properties of this user.
+ *
+ * @return \App\UserSetting[]
+ */
public function settings()
{
return $this->hasMany('App\UserSetting', 'user_id');
@@ -175,16 +271,6 @@
return $this->hasMany('App\Wallet');
}
- public function getJWTIdentifier()
- {
- return $this->getKey();
- }
-
- public function getJWTCustomClaims()
- {
- return [];
- }
-
public function setPasswordAttribute($password)
{
if (!empty($password)) {
@@ -204,4 +290,36 @@
);
}
}
+
+ /**
+ * User status mutator
+ *
+ * @throws \Exception
+ */
+ public function setStatusAttribute($status)
+ {
+ $new_status = 0;
+
+ $allowed_values = [
+ self::STATUS_NEW,
+ self::STATUS_ACTIVE,
+ self::STATUS_SUSPENDED,
+ self::STATUS_DELETED,
+ self::STATUS_LDAP_READY,
+ self::STATUS_IMAP_READY,
+ ];
+
+ foreach ($allowed_values as $value) {
+ if ($status & $value) {
+ $new_status |= $value;
+ $status ^= $value;
+ }
+ }
+
+ if ($status > 0) {
+ throw new \Exception("Invalid user status: {$status}");
+ }
+
+ $this->attributes['status'] = $new_status;
+ }
}
diff --git a/src/database/migrations/2014_10_12_000000_create_users_table.php b/src/database/migrations/2014_10_12_000000_create_users_table.php
--- a/src/database/migrations/2014_10_12_000000_create_users_table.php
+++ b/src/database/migrations/2014_10_12_000000_create_users_table.php
@@ -22,6 +22,7 @@
$table->timestamp('email_verified_at')->nullable();
$table->string('password')->nullable();
$table->string('password_ldap')->nullable();
+ $table->smallinteger('status');
$table->rememberToken();
$table->timestamps();
diff --git a/src/resources/lang/en/app.php b/src/resources/lang/en/app.php
--- a/src/resources/lang/en/app.php
+++ b/src/resources/lang/en/app.php
@@ -12,4 +12,11 @@
'planbutton' => 'Choose :plan',
+ 'process-user-new' => 'User registered',
+ 'process-user-ldap-ready' => 'User created',
+ 'process-user-imap-ready' => 'User mailbox created',
+ 'process-domain-new' => 'Custom domain registered',
+ 'process-domain-ldap-ready' => 'Custom domain created',
+ 'process-domain-verified' => 'Custom domain verified',
+ 'process-domain-confirmed' => 'Custom domain ownership verified',
];
diff --git a/src/tests/Feature/Controller/UsersTest.php b/src/tests/Feature/Controller/UsersTest.php
--- a/src/tests/Feature/Controller/UsersTest.php
+++ b/src/tests/Feature/Controller/UsersTest.php
@@ -2,6 +2,8 @@
namespace Tests\Feature\Controller;
+use App\Http\Controllers\API\UsersController;
+use App\Domain;
use App\User;
use Illuminate\Support\Str;
use Tests\TestCase;
@@ -15,29 +17,32 @@
{
parent::setUp();
- $user = User::where('email', 'UsersControllerTest1@UsersControllerTest.com')->delete();
+ User::where('email', 'UsersControllerTest1@userscontroller.com')->delete();
+ Domain::where('namespace', 'userscontroller.com')->delete();
}
/**
- * {@inheritDoc}
+ * Test fetching current user info
*/
- public function tearDown(): void
- {
- $user = User::where('email', 'UsersControllerTest1@UsersControllerTest.com')->delete();
- }
-
- public function testListUsers(): void
+ public function testInfo(): void
{
- $user = $this->getTestUser('UsersControllerTest1@UsersControllerTest.com');
+ $user = $this->getTestUser('UsersControllerTest1@userscontroller.com');
+ $domain = $this->getTestDomain('userscontroller.com', [
+ 'status' => Domain::STATUS_NEW,
+ 'type' => Domain::TYPE_PUBLIC,
+ ]);
- $response = $this->actingAs($user)->get("api/v4/users");
-
- $response->assertJsonCount(1);
+ $response = $this->actingAs($user)->get("api/auth/info");
+ $json = $response->json();
$response->assertStatus(200);
+ $this->assertEquals($user->id, $json['id']);
+ $this->assertEquals($user->email, $json['email']);
+ $this->assertEquals(User::STATUS_NEW, $json['status']);
+ $this->assertTrue(is_array($json['statusInfo']));
}
- public function testUserEntitlements()
+ public function testIndex(): void
{
$userA = $this->getTestUser('UserEntitlement2A@UserEntitlement.com');
@@ -50,4 +55,91 @@
$response = $this->actingAs($user)->get("/api/v4/users/{$userA->id}");
$response->assertStatus(404);
}
+
+ public function testLogin(): void
+ {
+ // TODO
+ $this->markTestIncomplete();
+ }
+
+ public function testLogout(): void
+ {
+ // TODO
+ $this->markTestIncomplete();
+ }
+
+ public function testRefresh(): void
+ {
+ // TODO
+ $this->markTestIncomplete();
+ }
+
+ public function testShow(): void
+ {
+ $user = $this->getTestUser('UsersControllerTest1@userscontroller.com');
+ $domain = $this->getTestDomain('userscontroller.com', [
+ 'status' => Domain::STATUS_NEW,
+ 'type' => Domain::TYPE_PUBLIC,
+ ]);
+
+ $user->status = User::STATUS_NEW;
+ $user->save();
+
+ $result = UsersController::statusInfo($user);
+
+ $this->assertSame('new', $result['status']);
+ $this->assertCount(3, $result['process']);
+ $this->assertSame('user-new', $result['process'][0]['label']);
+ $this->assertSame(true, $result['process'][0]['state']);
+ $this->assertSame('user-ldap-ready', $result['process'][1]['label']);
+ $this->assertSame(false, $result['process'][1]['state']);
+ $this->assertSame('user-imap-ready', $result['process'][2]['label']);
+ $this->assertSame(false, $result['process'][2]['state']);
+
+ $user->status |= User::STATUS_LDAP_READY | User::STATUS_IMAP_READY;
+ $user->save();
+
+ $result = UsersController::statusInfo($user);
+
+ $this->assertSame('new', $result['status']);
+ $this->assertCount(3, $result['process']);
+ $this->assertSame('user-new', $result['process'][0]['label']);
+ $this->assertSame(true, $result['process'][0]['state']);
+ $this->assertSame('user-ldap-ready', $result['process'][1]['label']);
+ $this->assertSame(true, $result['process'][1]['state']);
+ $this->assertSame('user-imap-ready', $result['process'][2]['label']);
+ $this->assertSame(true, $result['process'][2]['state']);
+
+ $user->status |= User::STATUS_ACTIVE;
+ $user->save();
+ $domain->status |= Domain::STATUS_VERIFIED;
+ $domain->type = Domain::TYPE_EXTERNAL;
+ $domain->save();
+
+ $result = UsersController::statusInfo($user);
+
+ $this->assertSame('active', $result['status']);
+ $this->assertCount(7, $result['process']);
+ $this->assertSame('user-new', $result['process'][0]['label']);
+ $this->assertSame(true, $result['process'][0]['state']);
+ $this->assertSame('user-ldap-ready', $result['process'][1]['label']);
+ $this->assertSame(true, $result['process'][1]['state']);
+ $this->assertSame('user-imap-ready', $result['process'][2]['label']);
+ $this->assertSame(true, $result['process'][2]['state']);
+ $this->assertSame('domain-new', $result['process'][3]['label']);
+ $this->assertSame(true, $result['process'][3]['state']);
+ $this->assertSame('domain-ldap-ready', $result['process'][4]['label']);
+ $this->assertSame(false, $result['process'][4]['state']);
+ $this->assertSame('domain-verified', $result['process'][5]['label']);
+ $this->assertSame(true, $result['process'][5]['state']);
+ $this->assertSame('domain-confirmed', $result['process'][6]['label']);
+ $this->assertSame(false, $result['process'][6]['state']);
+
+ $user->status |= User::STATUS_DELETED;
+ $user->save();
+
+ $result = UsersController::statusInfo($user);
+
+ $this->assertSame('deleted', $result['status']);
+ }
}
diff --git a/src/tests/Feature/DomainTest.php b/src/tests/Feature/DomainTest.php
--- a/src/tests/Feature/DomainTest.php
+++ b/src/tests/Feature/DomainTest.php
@@ -17,7 +17,51 @@
{
parent::setUp();
- Domain::where('namespace', 'public-active.com')->delete();
+ Domain::where('namespace', 'public-active.com')
+ ->orWhere('namespace', 'gmail.com')->delete();
+ }
+
+ /**
+ * Test domain creating jobs
+ */
+ public function testCreateJobs(): void
+ {
+ // Fake the queue, assert that no jobs were pushed...
+ Queue::fake();
+ Queue::assertNothingPushed();
+
+ $domain = Domain::create([
+ 'namespace' => 'gmail.com',
+ 'status' => Domain::STATUS_NEW,
+ 'type' => Domain::TYPE_EXTERNAL,
+ ]);
+
+ Queue::assertPushed(\App\Jobs\ProcessDomainCreate::class, 1);
+ Queue::assertPushed(\App\Jobs\ProcessDomainCreate::class, function ($job) use ($domain) {
+ $job_domain = TestCase::getObjectProperty($job, 'domain');
+
+ return $job_domain->id === $domain->id
+ && $job_domain->namespace === $domain->namespace;
+ });
+
+ Queue::assertPushedWithChain(\App\Jobs\ProcessDomainCreate::class, [
+ \App\Jobs\ProcessDomainVerify::class,
+ ]);
+
+/*
+ FIXME: Looks like we can't really do detailed assertions on chained jobs
+ Another thing to consider is if we maybe should run these jobs
+ independently (not chained) and make sure there's no race-condition
+ in status update
+
+ Queue::assertPushed(\App\Jobs\ProcessDomainVerify::class, 1);
+ Queue::assertPushed(\App\Jobs\ProcessDomainVerify::class, function ($job) use ($domain) {
+ $job_domain = TestCase::getObjectProperty($job, 'domain');
+
+ return $job_domain->id === $domain->id
+ && $job_domain->namespace === $domain->namespace;
+ });
+*/
}
/**
@@ -29,9 +73,7 @@
$this->assertNotContains('public-active.com', $public_domains);
- // Fake the queue, assert that no jobs were pushed...
Queue::fake();
- Queue::assertNothingPushed();
$domain = Domain::create([
'namespace' => 'public-active.com',
@@ -43,14 +85,6 @@
$public_domains = Domain::getPublicDomains();
$this->assertNotContains('public-active.com', $public_domains);
- Queue::assertPushed(\App\Jobs\ProcessDomainCreate::class, 1);
- Queue::assertPushed(\App\Jobs\ProcessDomainCreate::class, function ($job) use ($domain) {
- $job_domain = TestCase::getObjectProperty($job, 'domain');
-
- return $job_domain->id === $domain->id
- && $job_domain->namespace === $domain->namespace;
- });
-
$domain = Domain::where('namespace', 'public-active.com')->first();
$domain->status = Domain::STATUS_ACTIVE;
$domain->save();
diff --git a/src/tests/Feature/Jobs/ProcessDomainCreateTest.php b/src/tests/Feature/Jobs/ProcessDomainCreateTest.php
new file mode 100644
--- /dev/null
+++ b/src/tests/Feature/Jobs/ProcessDomainCreateTest.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Tests\Feature\Jobs;
+
+use App\Jobs\ProcessDomainCreate;
+use App\Domain;
+use Illuminate\Support\Facades\Mail;
+use Tests\TestCase;
+
+class DomainCreateTest extends TestCase
+{
+ use \Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
+
+ /**
+ * {@inheritDoc}
+ */
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ Domain::where('namespace', 'domain-create-test.com')->delete();
+ }
+
+ /**
+ * Test job handle
+ */
+ public function testHandle(): void
+ {
+ $domain = $this->getTestDomain(
+ 'domain-create-test.com',
+ [
+ 'status' => Domain::STATUS_NEW,
+ 'type' => Domain::TYPE_EXTERNAL,
+ ]
+ );
+
+ $this->assertFalse($domain->isLdapReady());
+
+ $mock = \Mockery::mock('alias:App\Backends\LDAP');
+ $mock->shouldReceive('createDomain')
+ ->once()
+ ->with($domain)
+ ->andReturn(null);
+
+ $job = new ProcessDomainCreate($domain);
+ $job->handle();
+
+ $this->assertTrue($domain->fresh()->isLdapReady());
+ }
+}
diff --git a/src/tests/Feature/Jobs/ProcessDomainVerifyTest.php b/src/tests/Feature/Jobs/ProcessDomainVerifyTest.php
new file mode 100644
--- /dev/null
+++ b/src/tests/Feature/Jobs/ProcessDomainVerifyTest.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace Tests\Feature\Jobs;
+
+use App\Jobs\ProcessDomainVerify;
+use App\Domain;
+use Illuminate\Support\Facades\Mail;
+use Tests\TestCase;
+
+class DomainVerifyTest extends TestCase
+{
+ /**
+ * {@inheritDoc}
+ */
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ Domain::where('namespace', 'gmail.com')
+ ->orWhere('namespace', 'some-non-existing-domain.fff')
+ ->delete();
+ }
+
+ /**
+ * Test job handle (existing domain)
+ *
+ * @group dns
+ */
+ public function testHandle(): void
+ {
+ $domain = $this->getTestDomain(
+ 'gmail.com',
+ [
+ 'status' => Domain::STATUS_NEW,
+ 'type' => Domain::TYPE_EXTERNAL,
+ ]
+ );
+
+ $this->assertFalse($domain->isVerified());
+
+ $job = new ProcessDomainVerify($domain);
+ $job->handle();
+
+ $this->assertTrue($domain->fresh()->isVerified());
+ }
+
+ /**
+ * Test job handle (non-existing domain)
+ *
+ * @group dns
+ */
+ public function testHandleNonExisting(): void
+ {
+ $domain = $this->getTestDomain(
+ 'some-non-existing-domain.fff',
+ [
+ 'status' => Domain::STATUS_NEW,
+ 'type' => Domain::TYPE_EXTERNAL,
+ ]
+ );
+
+ $this->assertFalse($domain->isVerified());
+
+ $job = new ProcessDomainVerify($domain);
+ $job->handle();
+
+ $this->assertFalse($domain->fresh()->isVerified());
+ }
+}
diff --git a/src/tests/Feature/Jobs/UserCreateTest.php b/src/tests/Feature/Jobs/UserCreateTest.php
new file mode 100644
--- /dev/null
+++ b/src/tests/Feature/Jobs/UserCreateTest.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Tests\Feature\Jobs;
+
+use App\Jobs\ProcessUserCreate;
+use App\User;
+use Illuminate\Support\Facades\Mail;
+use Tests\TestCase;
+
+class UserCreateTest extends TestCase
+{
+ use \Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
+
+ /**
+ * {@inheritDoc}
+ */
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ User::where('email', 'new-job-user@' . \config('app.domain'))->delete();
+ }
+
+ /**
+ * Test job handle
+ */
+ public function testHandle(): void
+ {
+ $user = $this->getTestUser('new-job-user@' . \config('app.domain'));
+
+ $this->assertFalse($user->isLdapReady());
+
+ $mock = \Mockery::mock('alias:App\Backends\LDAP');
+ $mock->shouldReceive('createUser')
+ ->once()
+ ->with($user)
+ ->andReturn(null);
+
+ $job = new ProcessUserCreate($user);
+ $job->handle();
+
+ $this->assertTrue($user->fresh()->isLdapReady());
+ }
+}
diff --git a/src/tests/Feature/Jobs/UserVerify.php b/src/tests/Feature/Jobs/UserVerify.php
new file mode 100644
--- /dev/null
+++ b/src/tests/Feature/Jobs/UserVerify.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace Tests\Feature\Jobs;
+
+use App\Jobs\ProcessUserVerify;
+use App\User;
+use Illuminate\Support\Facades\Mail;
+use Tests\TestCase;
+
+class UserVerifyTest extends TestCase
+{
+ use \Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
+
+ /**
+ * {@inheritDoc}
+ */
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ User::where('email', 'new-job-user@' . \config('app.domain'))->delete();
+ }
+
+ /**
+ * Test job handle
+ */
+ public function testHandle(): void
+ {
+ $user = $this->getTestUser('new-job-user@' . \config('app.domain'));
+
+ $this->assertFalse($user->isImapReady());
+
+ $mock = \Mockery::mock('alias:App\Backends\IMAP');
+ $mock->shouldReceive('verifyAccount')
+ ->once()
+ ->with($user->email)
+ ->andReturn(false);
+
+ $job = new ProcessUserVerify($user);
+ $job->handle();
+
+ $this->assertTrue($user->fresh()->isImapReady() === false);
+
+ $mock->shouldReceive('verifyAccount')
+ ->once()
+ ->with($user->email)
+ ->andReturn(true);
+
+ $job->handle();
+
+ $this->assertTrue($user->fresh()->isImapReady());
+ }
+}
diff --git a/src/tests/Feature/UserTest.php b/src/tests/Feature/UserTest.php
--- a/src/tests/Feature/UserTest.php
+++ b/src/tests/Feature/UserTest.php
@@ -35,6 +35,24 @@
return $job_user->id === $user->id
&& $job_user->email === $user->email;
});
+
+ Queue::assertPushedWithChain(\App\Jobs\ProcessUserCreate::class, [
+ \App\Jobs\ProcessUserVerify::class,
+ ]);
+/*
+ FIXME: Looks like we can't really do detailed assertions on chained jobs
+ Another thing to consider is if we maybe should run these jobs
+ independently (not chained) and make sure there's no race-condition
+ in status update
+
+ Queue::assertPushed(\App\Jobs\ProcessUserVerify::class, 1);
+ Queue::assertPushed(\App\Jobs\ProcessUserVerify::class, function ($job) use ($user) {
+ $job_user = TestCase::getObjectProperty($job, 'user');
+
+ return $job_user->id === $user->id
+ && $job_user->email === $user->email;
+ });
+*/
}
/**
diff --git a/src/tests/Unit/DomainTest.php b/src/tests/Unit/DomainTest.php
--- a/src/tests/Unit/DomainTest.php
+++ b/src/tests/Unit/DomainTest.php
@@ -10,7 +10,7 @@
/**
* Test basic Domain funtionality
*/
- public function testDomainStatus()
+ public function testDomainStatus(): void
{
$statuses = [
Domain::STATUS_NEW,
@@ -18,6 +18,8 @@
Domain::STATUS_CONFIRMED,
Domain::STATUS_SUSPENDED,
Domain::STATUS_DELETED,
+ Domain::STATUS_LDAP_READY,
+ Domain::STATUS_VERIFIED,
];
$domains = \App\Utils::powerSet($statuses);
@@ -36,13 +38,30 @@
$this->assertTrue($domain->isConfirmed() === in_array(Domain::STATUS_CONFIRMED, $domain_statuses));
$this->assertTrue($domain->isSuspended() === in_array(Domain::STATUS_SUSPENDED, $domain_statuses));
$this->assertTrue($domain->isDeleted() === in_array(Domain::STATUS_DELETED, $domain_statuses));
+ $this->assertTrue($domain->isLdapReady() === in_array(Domain::STATUS_LDAP_READY, $domain_statuses));
+ $this->assertTrue($domain->isVerified() === in_array(Domain::STATUS_VERIFIED, $domain_statuses));
}
}
+ /**
+ * Test setStatusAttribute exception
+ */
+ public function testDomainStatusInvalid(): void
+ {
+ $this->expectException(\Exception::class);
+
+ $domain = new Domain(
+ [
+ 'namespace' => 'test.com',
+ 'status' => 1234567,
+ ]
+ );
+ }
+
/**
* Test basic Domain funtionality
*/
- public function testDomainType()
+ public function testDomainType(): void
{
$types = [
Domain::TYPE_PUBLIC,
@@ -66,4 +85,15 @@
$this->assertTrue($domain->isExternal() === in_array(Domain::TYPE_EXTERNAL, $domain_types));
}
}
+
+ /**
+ * Test domain verification
+ *
+ * @group dns
+ */
+ public function testVerifyDomain(): void
+ {
+ // TODO
+ $this->markTestIncomplete();
+ }
}
diff --git a/src/tests/Unit/UserTest.php b/src/tests/Unit/UserTest.php
new file mode 100644
--- /dev/null
+++ b/src/tests/Unit/UserTest.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Tests\Unit;
+
+use App\User;
+use Tests\TestCase;
+
+class UserTest extends TestCase
+{
+ /**
+ * Test basic User funtionality
+ */
+ public function testUserStatus()
+ {
+ $statuses = [
+ User::STATUS_NEW,
+ User::STATUS_ACTIVE,
+ User::STATUS_SUSPENDED,
+ User::STATUS_DELETED,
+ User::STATUS_IMAP_READY,
+ User::STATUS_LDAP_READY,
+ ];
+
+ $users = \App\Utils::powerSet($statuses);
+
+ foreach ($users as $user_statuses) {
+ $user = new User(
+ [
+ 'email' => 'user@email.com',
+ 'status' => \array_sum($user_statuses),
+ ]
+ );
+
+ $this->assertTrue($user->isNew() === in_array(User::STATUS_NEW, $user_statuses));
+ $this->assertTrue($user->isActive() === in_array(User::STATUS_ACTIVE, $user_statuses));
+ $this->assertTrue($user->isSuspended() === in_array(User::STATUS_SUSPENDED, $user_statuses));
+ $this->assertTrue($user->isDeleted() === in_array(User::STATUS_DELETED, $user_statuses));
+ $this->assertTrue($user->isLdapReady() === in_array(User::STATUS_LDAP_READY, $user_statuses));
+ $this->assertTrue($user->isImapReady() === in_array(User::STATUS_IMAP_READY, $user_statuses));
+ }
+ }
+
+ /**
+ * Test setStatusAttribute exception
+ */
+ public function testUserStatusInvalid(): void
+ {
+ $this->expectException(\Exception::class);
+
+ $user = new User(
+ [
+ 'email' => 'user@email.com',
+ 'status' => 1234567,
+ ]
+ );
+ }
+}

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 8, 9:30 PM (1 d, 9 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18835300
Default Alt Text
D925.1775683852.diff (35 KB)

Event Timeline