Skip to content

Commit 782eb68

Browse files
authored
Merge pull request #306 from binaryfire/refactor-enum-handling-to-str-helpers
refactor(sanctum): use Str::from() helpers for BackedEnum handling
2 parents d13a0c7 + ef1978d commit 782eb68

File tree

5 files changed

+97
-5
lines changed

5 files changed

+97
-5
lines changed

src/sanctum/src/HasApiTokens.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,7 @@ public function tokenCant(BackedEnum|string $ability): bool
5555
*/
5656
public function createToken(string $name, array $abilities = ['*'], ?DateTimeInterface $expiresAt = null): NewAccessToken
5757
{
58-
$abilities = array_map(
59-
fn ($ability) => $ability instanceof BackedEnum ? $ability->value : $ability,
60-
$abilities
61-
);
58+
$abilities = Str::fromAll($abilities);
6259

6360
$plainTextToken = $this->generateTokenString();
6461

src/sanctum/src/PersonalAccessToken.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Hypervel\Context\ApplicationContext;
1515
use Hypervel\Database\Eloquent\Model;
1616
use Hypervel\Sanctum\Contracts\HasAbilities;
17+
use Hypervel\Support\Str;
1718

1819
/**
1920
* @property int|string $id
@@ -155,7 +156,7 @@ public static function findTokenable(PersonalAccessToken $accessToken): ?Authent
155156
*/
156157
public function can(BackedEnum|string $ability): bool
157158
{
158-
$ability = $ability instanceof BackedEnum ? $ability->value : $ability;
159+
$ability = Str::from($ability);
159160

160161
return in_array('*', $this->abilities)
161162
|| array_key_exists($ability, array_flip($this->abilities));

tests/Sanctum/HasApiTokensTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Hypervel\Sanctum\PersonalAccessToken;
88
use Hypervel\Sanctum\TransientToken;
99
use Hypervel\Testbench\TestCase;
10+
use Hypervel\Tests\Sanctum\Stub\TokenAbility;
1011
use Hypervel\Tests\Sanctum\Stub\UserWithApiTokens;
1112

1213
/**
@@ -52,4 +53,41 @@ public function testCurrentAccessTokenGetter(): void
5253

5354
$this->assertSame($token, $user->currentAccessToken());
5455
}
56+
57+
public function testTokenCanWithBackedEnum(): void
58+
{
59+
$user = new UserWithApiTokens();
60+
61+
$token = new PersonalAccessToken();
62+
$token->abilities = ['posts:read', 'posts:write'];
63+
64+
$user->withAccessToken($token);
65+
66+
$this->assertTrue($user->tokenCan(TokenAbility::PostsRead));
67+
$this->assertTrue($user->tokenCan(TokenAbility::PostsWrite));
68+
$this->assertFalse($user->tokenCan(TokenAbility::UsersRead));
69+
}
70+
71+
public function testTokenCantWithBackedEnum(): void
72+
{
73+
$user = new UserWithApiTokens();
74+
75+
$token = new PersonalAccessToken();
76+
$token->abilities = ['posts:read'];
77+
78+
$user->withAccessToken($token);
79+
80+
$this->assertFalse($user->tokenCant(TokenAbility::PostsRead));
81+
$this->assertTrue($user->tokenCant(TokenAbility::PostsWrite));
82+
}
83+
84+
public function testTransientTokenCanWithBackedEnum(): void
85+
{
86+
$user = new UserWithApiTokens();
87+
$user->withAccessToken(new TransientToken());
88+
89+
// TransientToken allows everything
90+
$this->assertTrue($user->tokenCan(TokenAbility::PostsRead));
91+
$this->assertTrue($user->tokenCan(TokenAbility::UsersWrite));
92+
}
5593
}

tests/Sanctum/PersonalAccessTokenTest.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Hypervel\Tests\Sanctum;
66

77
use Hypervel\Sanctum\PersonalAccessToken;
8+
use Hypervel\Tests\Sanctum\Stub\TokenAbility;
89
use PHPUnit\Framework\TestCase;
910

1011
/**
@@ -33,4 +34,46 @@ public function testCanDetermineWhatItCanAndCantDo(): void
3334
$this->assertTrue($token->can('foo'));
3435
$this->assertTrue($token->can('bar'));
3536
}
37+
38+
public function testCanCheckAbilitiesWithBackedEnum(): void
39+
{
40+
$token = new PersonalAccessToken();
41+
$token->abilities = ['posts:read', 'posts:write'];
42+
43+
$this->assertTrue($token->can(TokenAbility::PostsRead));
44+
$this->assertTrue($token->can(TokenAbility::PostsWrite));
45+
$this->assertFalse($token->can(TokenAbility::UsersRead));
46+
}
47+
48+
public function testCantCheckAbilitiesWithBackedEnum(): void
49+
{
50+
$token = new PersonalAccessToken();
51+
$token->abilities = ['posts:read'];
52+
53+
$this->assertFalse($token->cant(TokenAbility::PostsRead));
54+
$this->assertTrue($token->cant(TokenAbility::PostsWrite));
55+
}
56+
57+
public function testWildcardAbilityWorksWithBackedEnum(): void
58+
{
59+
$token = new PersonalAccessToken();
60+
$token->abilities = ['*'];
61+
62+
$this->assertTrue($token->can(TokenAbility::PostsRead));
63+
$this->assertTrue($token->can(TokenAbility::PostsWrite));
64+
$this->assertTrue($token->can(TokenAbility::UsersRead));
65+
}
66+
67+
public function testMixedStringAndEnumAbilitiesWork(): void
68+
{
69+
$token = new PersonalAccessToken();
70+
$token->abilities = ['posts:read', 'legacy-ability'];
71+
72+
// Enum check
73+
$this->assertTrue($token->can(TokenAbility::PostsRead));
74+
// String check for same value
75+
$this->assertTrue($token->can('posts:read'));
76+
// String check for legacy
77+
$this->assertTrue($token->can('legacy-ability'));
78+
}
3679
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Hypervel\Tests\Sanctum\Stub;
6+
7+
enum TokenAbility: string
8+
{
9+
case PostsRead = 'posts:read';
10+
case PostsWrite = 'posts:write';
11+
case UsersRead = 'users:read';
12+
case UsersWrite = 'users:write';
13+
}

0 commit comments

Comments
 (0)