Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ type User {

"Whether or not the user is a global administrator."
admin: Boolean! @filterable

projects(
filters: _ @filter
): [Project!]! @hasMany(type: CONNECTION, scopes: ["forUser"]) @orderBy(column: "id")
}


Expand Down
168 changes: 128 additions & 40 deletions tests/Feature/GraphQL/UserTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,25 @@

namespace Tests\Feature\GraphQL;

use App\Models\User;
use App\Models\Project;
use Exception;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase;
use Tests\Traits\CreatesProjects;
use Tests\Traits\CreatesUsers;

class UserTypeTest extends TestCase
{
use CreatesProjects;
use CreatesUsers;
use DatabaseTransactions;

private User $normalUser;
private User $adminUser;

protected function setUp(): void
{
parent::setUp();

$this->normalUser = $this->makeNormalUser();
$this->adminUser = $this->makeAdminUser();
}

protected function tearDown(): void
{
$this->normalUser->delete();
$this->adminUser->delete();

parent::tearDown();
}

public function testBasicFieldAccess(): void
{
$this->actingAs($this->normalUser)->graphQL('
$normalUser = $this->makeNormalUser();

$this->actingAs($normalUser)->graphQL('
query {
me {
id
Expand All @@ -42,58 +29,73 @@ public function testBasicFieldAccess(): void
lastname
institution
admin
projects {
edges {
node {
id
}
}
}
}
}
')->assertExactJson([
'data' => [
'me' => [
'id' => (string) $this->normalUser->id,
'email' => $this->normalUser->email,
'firstname' => $this->normalUser->firstname,
'lastname' => $this->normalUser->lastname,
'institution' => $this->normalUser->institution,
'admin' => $this->normalUser->admin,
'id' => (string) $normalUser->id,
'email' => $normalUser->email,
'firstname' => $normalUser->firstname,
'lastname' => $normalUser->lastname,
'institution' => $normalUser->institution,
'admin' => $normalUser->admin,
'projects' => [
'edges' => [],
],
],
],
]);
}

public function testCanSeeOwnEmail(): void
{
$this->actingAs($this->normalUser)->graphQL('
$normalUser = $this->makeNormalUser();

$this->actingAs($normalUser)->graphQL('
query($userid: ID) {
user(id: $userid) {
id
email
}
}
', [
'userid' => $this->normalUser->id,
'userid' => $normalUser->id,
])->assertExactJson([
'data' => [
'user' => [
'id' => (string) $this->normalUser->id,
'email' => $this->normalUser->email,
'id' => (string) $normalUser->id,
'email' => $normalUser->email,
],
],
]);
}

public function testCannotSeeEmailForOtherUsers(): void
{
$this->actingAs($this->normalUser)->graphQL('
$normalUser = $this->makeNormalUser();
$adminUser = $this->makeNormalUser();

$this->actingAs($normalUser)->graphQL('
query($userid: ID) {
user(id: $userid) {
id
email
}
}
', [
'userid' => $this->adminUser->id,
'userid' => $adminUser->id,
])->assertExactJson([
'data' => [
'user' => [
'id' => (string) $this->adminUser->id,
'id' => (string) $adminUser->id,
'email' => null,
],
],
Expand All @@ -102,6 +104,8 @@ public function testCannotSeeEmailForOtherUsers(): void

public function testAnonUsersCannotSeeEmails(): void
{
$normalUser = $this->makeNormalUser();

$this->graphQL('
query($userid: ID) {
user(id: $userid) {
Expand All @@ -110,11 +114,11 @@ public function testAnonUsersCannotSeeEmails(): void
}
}
', [
'userid' => $this->normalUser->id,
'userid' => $normalUser->id,
])->assertExactJson([
'data' => [
'user' => [
'id' => (string) $this->normalUser->id,
'id' => (string) $normalUser->id,
'email' => null,
],
],
Expand All @@ -123,20 +127,104 @@ public function testAnonUsersCannotSeeEmails(): void

public function testAdminCanSeeAllEmails(): void
{
$this->actingAs($this->adminUser)->graphQL('
$normalUser = $this->makeNormalUser();
$adminUser = $this->makeAdminUser();

$this->actingAs($adminUser)->graphQL('
query($userid: ID) {
user(id: $userid) {
id
email
}
}
', [
'userid' => $this->normalUser->id,
'userid' => $normalUser->id,
])->assertExactJson([
'data' => [
'user' => [
'id' => (string) $normalUser->id,
'email' => $normalUser->email,
],
],
]);
}

/**
* @return array<array<mixed>>
*/
public static function projectsRelationshipVisibilityCases(): array
{
return [
[null, true, false, false],
['normal', true, true, false],
['project_member', true, true, true],
['project_admin', true, true, true],
['admin', true, true, true],
];
}

#[DataProvider('projectsRelationshipVisibilityCases')]
public function testProjectsRelationshipVisibility(
?string $user,
bool $canSeePublicProject,
bool $canSeeProtectedProject,
bool $canSeePrivateProject,
): void {
$publicProject = $this->makePublicProject();
$protectedProject = $this->makeProtectedProject();
$privateProject = $this->makePrivateProject();

$projectUser = $this->makeNormalUser();
$publicProject->users()->attach($projectUser, ['role' => Project::PROJECT_USER]);
$protectedProject->users()->attach($projectUser, ['role' => Project::PROJECT_USER]);
$privateProject->users()->attach($projectUser, ['role' => Project::PROJECT_USER]);

if ($user === 'normal') {
$user = $this->makeNormalUser();
} elseif ($user === 'project_member') {
$user = $this->makeNormalUser();
$publicProject->users()->attach($user, ['role' => Project::PROJECT_USER]);
$protectedProject->users()->attach($user, ['role' => Project::PROJECT_USER]);
$privateProject->users()->attach($user, ['role' => Project::PROJECT_USER]);
} elseif ($user === 'project_admin') {
$user = $this->makeNormalUser();
$publicProject->users()->attach($user, ['role' => Project::PROJECT_ADMIN]);
$protectedProject->users()->attach($user, ['role' => Project::PROJECT_ADMIN]);
$privateProject->users()->attach($user, ['role' => Project::PROJECT_ADMIN]);
} elseif ($user === 'admin') {
$user = $this->makeAdminUser();
} elseif ($user === null) {
$user = null;
} else {
throw new Exception('Invalid user.');
}

($user === null ? $this : $this->actingAs($user))->graphQL('
query($userid: ID) {
user(id: $userid) {
id
projects {
edges {
node {
id
}
}
}
}
}
', [
'userid' => $projectUser->id,
])->assertExactJson([
'data' => [
'user' => [
'id' => (string) $this->normalUser->id,
'email' => $this->normalUser->email,
'id' => (string) $projectUser->id,
'projects' => [
'edges' => [
...($canSeePublicProject ? [['node' => ['id' => (string) $publicProject->id]]] : []),
...($canSeeProtectedProject ? [['node' => ['id' => (string) $protectedProject->id]]] : []),
...($canSeePrivateProject ? [['node' => ['id' => (string) $privateProject->id]]] : []),
],
],
],
],
]);
Expand Down