-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: auto assign users upon registration
- Loading branch information
Showing
5 changed files
with
242 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<?php | ||
|
||
namespace PressbooksMultiInstitution\Actions; | ||
|
||
use Illuminate\Support\Str; | ||
use PressbooksMultiInstitution\Models\Institution; | ||
|
||
class AssignUserToInstitution | ||
{ | ||
public function handle(int $userId): bool | ||
{ | ||
$user = get_userdata($userId); | ||
|
||
if (! $user) { | ||
return false; | ||
} | ||
|
||
$email = Str::of($user->user_email); | ||
|
||
$domain = (string) $email->after('@')->trim(); | ||
|
||
/** @var Institution $institution */ | ||
$institution = Institution::query()->whereRelation('domains', 'domain', $domain)->first(); | ||
|
||
if (! $institution) { | ||
return false; | ||
} | ||
|
||
$institution->users()->create([ | ||
'user_id' => $userId, | ||
]); | ||
|
||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
<?php | ||
|
||
namespace Tests\Feature\Actions; | ||
|
||
use Illuminate\Database\Capsule\Manager; | ||
use PressbooksMultiInstitution\Bootstrap; | ||
use PressbooksMultiInstitution\Models\Institution; | ||
use PressbooksMultiInstitution\Actions\AssignUserToInstitution; | ||
use PressbooksMultiInstitution\Models\InstitutionUser; | ||
use ReflectionFunction; | ||
use Tests\TestCase; | ||
|
||
class AssignUserToInstitutionTest extends TestCase | ||
{ | ||
/** | ||
* @test | ||
*/ | ||
public function it_register_hook_action(): void | ||
{ | ||
$this->assertTrue( | ||
has_action('user_register') | ||
); | ||
|
||
$this->assertHasCallbackAction('user_register', Bootstrap::class); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function it_associates_users_with_institutions(): void | ||
{ | ||
$id = $this->newUser([ | ||
'user_email' => 'johndoe@fakedomain.edu', | ||
]); | ||
|
||
/** @var Institution $institution */ | ||
$institution = Institution::query()->create([ | ||
'name' => 'Fake Institution', | ||
]); | ||
|
||
$institution->domains()->create([ | ||
'domain' => 'fakedomain.edu', | ||
]); | ||
|
||
$this->assertDatabaseEmpty('institutions_users'); | ||
|
||
$this->assertTrue( | ||
(new AssignUserToInstitution)->handle($id) | ||
); | ||
|
||
$this->assertDatabaseCount('institutions_users', 1); | ||
|
||
$this->assertEquals( | ||
1, | ||
InstitutionUser::query() | ||
->where('user_id', $id) | ||
->where('institution_id', $institution->id) | ||
->count() | ||
); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function it_does_not_associate_when_email_domain_does_not_match(): void | ||
{ | ||
$id = $this->newUser([ | ||
'user_email' => 'johndoe@anotherfakedomain.edu', | ||
]); | ||
|
||
/** @var Institution $institution */ | ||
$institution = Institution::query()->create([ | ||
'name' => 'Fake Institution', | ||
]); | ||
|
||
$institution->domains()->create([ | ||
'domain' => 'fakedomain.edu', | ||
]); | ||
|
||
$this->assertDatabaseEmpty('institutions_users'); | ||
|
||
$this->assertFalse( | ||
(new AssignUserToInstitution)->handle($id) | ||
); | ||
|
||
$this->assertDatabaseEmpty('institutions_users'); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function it_does_not_associate_invalid_users(): void | ||
{ | ||
$this->newUser([ | ||
'user_email' => 'johndoe@fakedomain.edu', | ||
]); | ||
|
||
/** @var Institution $institution */ | ||
$institution = Institution::query()->create([ | ||
'name' => 'Fake Institution', | ||
]); | ||
|
||
$institution->domains()->create([ | ||
'domain' => 'fakedomain.edu', | ||
]); | ||
|
||
$this->assertDatabaseEmpty('institutions_users'); | ||
|
||
$this->assertFalse( | ||
(new AssignUserToInstitution)->handle(9999) | ||
); | ||
|
||
$this->assertDatabaseEmpty('institutions_users'); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function it_does_not_associate_when_there_are_no_institutions(): void | ||
{ | ||
$id = $this->newUser([ | ||
'user_email' => 'johndoe@fakedomain.edu', | ||
]); | ||
|
||
$this->assertDatabaseEmpty('institutions_users'); | ||
|
||
$this->assertFalse( | ||
(new AssignUserToInstitution)->handle($id) | ||
); | ||
|
||
$this->assertDatabaseEmpty('institutions_users'); | ||
} | ||
|
||
protected function assertDatabaseCount(string $table, int $count): void | ||
{ | ||
/** @var Manager $db */ | ||
$db = app('db'); | ||
|
||
$this->assertEquals($count, $db->table($table)->count()); | ||
} | ||
|
||
protected function assertDatabaseEmpty(string $table): void | ||
{ | ||
$this->assertDatabaseCount($table, 0); | ||
} | ||
|
||
protected function assertHasCallbackAction(string $hook, string $class): bool | ||
{ | ||
global $wp_filter; | ||
|
||
foreach ($wp_filter[$hook] ?? [] as $callbacks) { | ||
foreach ($callbacks as $callback) { | ||
if (is_array($callback['function'])) { | ||
continue; | ||
} | ||
|
||
$closure = new ReflectionFunction($callback['function']); | ||
|
||
if($closure->getClosureScopeClass()?->getName() === $class) { | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
protected function newUser(array $properties = []): int | ||
{ | ||
global $wpdb; | ||
|
||
$wpdb->query('START TRANSACTION'); | ||
|
||
$wpdb->delete($wpdb->users, [ | ||
'user_login' => $properties['user_login'] ?? 'johndoe', | ||
]); | ||
|
||
$user = $this->factory()->user->create([ | ||
'first_name' => 'John', | ||
'last_name' => 'Doe', | ||
'user_login' => 'johndoe', | ||
'user_email' => 'johndoe@fakedomain.edu', | ||
...$properties | ||
]); | ||
|
||
$wpdb->query('COMMIT'); | ||
|
||
return $user; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters