Skip to content

Commit 20fead7

Browse files
authored
feat: add API endpoint to retrieve license details by key (#194)
1 parent 62a6f27 commit 20fead7

File tree

5 files changed

+189
-13
lines changed

5 files changed

+189
-13
lines changed

app/Http/Controllers/Api/LicenseController.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use App\Enums\LicenseSource;
66
use App\Enums\Subscription;
77
use App\Http\Controllers\Controller;
8+
use App\Http\Resources\Api\LicenseResource;
89
use App\Jobs\CreateAnystackLicenseJob;
910
use App\Models\License;
1011
use App\Models\User;
@@ -47,11 +48,21 @@ public function store(Request $request)
4748
// Since we're using dispatchSync, the job has completed by this point
4849
// Find the created license
4950
$license = License::where('user_id', $user->id)
51+
->with('user')
5052
->where('policy_name', $subscription->value)
5153
->where('source', LicenseSource::Bifrost)
5254
->latest()
5355
->firstOrFail();
5456

55-
return response()->json($license);
57+
return new LicenseResource($license);
58+
}
59+
60+
public function show(string $key)
61+
{
62+
$license = License::where('key', $key)
63+
->with('user')
64+
->firstOrFail();
65+
66+
return new LicenseResource($license);
5667
}
5768
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace App\Http\Resources\Api;
4+
5+
use Illuminate\Http\Request;
6+
use Illuminate\Http\Resources\Json\JsonResource;
7+
8+
class LicenseResource extends JsonResource
9+
{
10+
/**
11+
* Transform the resource into an array.
12+
*
13+
* @return array<string, mixed>
14+
*/
15+
public function toArray(Request $request): array
16+
{
17+
return [
18+
'id' => $this->id,
19+
'anystack_id' => $this->anystack_id,
20+
'key' => $this->key,
21+
'policy_name' => $this->policy_name,
22+
'source' => $this->source,
23+
'expires_at' => $this->expires_at,
24+
'created_at' => $this->created_at,
25+
'updated_at' => $this->updated_at,
26+
'email' => $this->user->email,
27+
];
28+
}
29+
}

routes/api.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
Route::middleware('auth.api_key')->group(function () {
1919
Route::post('/licenses', [LicenseController::class, 'store']);
20+
Route::get('/licenses/{key}', [LicenseController::class, 'show']);
2021
});
2122

2223
Route::middleware('auth:sanctum')->group(function () {

tests/Feature/Api/CreateLicenseTest.php

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,22 @@ public function test_creates_license_with_bifrost_source()
129129

130130
$response->assertStatus(200)
131131
->assertJsonStructure([
132-
'id',
133-
'user_id',
134-
'policy_name',
135-
'source',
136-
'key',
137-
'created_at',
138-
'updated_at',
132+
'data' => [
133+
'id',
134+
'anystack_id',
135+
'key',
136+
'policy_name',
137+
'source',
138+
'expires_at',
139+
'created_at',
140+
'updated_at',
141+
'email',
142+
],
143+
])
144+
->assertJson([
145+
'data' => [
146+
'email' => '[email protected]',
147+
],
139148
]);
140149

141150
// Verify the license was created with correct attributes
@@ -171,11 +180,22 @@ public function test_creates_license_for_existing_user()
171180

172181
$response->assertStatus(200)
173182
->assertJsonStructure([
174-
'id',
175-
'user_id',
176-
'policy_name',
177-
'source',
178-
'key',
183+
'data' => [
184+
'id',
185+
'anystack_id',
186+
'key',
187+
'policy_name',
188+
'source',
189+
'expires_at',
190+
'created_at',
191+
'updated_at',
192+
'email',
193+
],
194+
])
195+
->assertJson([
196+
'data' => [
197+
'email' => '[email protected]',
198+
],
179199
]);
180200

181201
// Verify license was created for the existing user

tests/Feature/Api/GetLicenseTest.php

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
namespace Tests\Feature\Api;
4+
5+
use App\Models\License;
6+
use App\Models\User;
7+
use Illuminate\Foundation\Testing\RefreshDatabase;
8+
use Tests\TestCase;
9+
10+
class GetLicenseTest extends TestCase
11+
{
12+
use RefreshDatabase;
13+
14+
public function test_requires_authentication()
15+
{
16+
$user = User::factory()->create();
17+
$license = License::factory()->create([
18+
'user_id' => $user->id,
19+
'key' => 'TEST-KEY-123',
20+
]);
21+
22+
$response = $this->getJson('/api/licenses/'.$license->key);
23+
24+
$response->assertStatus(401);
25+
}
26+
27+
public function test_returns_404_for_non_existent_license()
28+
{
29+
$token = config('services.bifrost.api_key');
30+
31+
$response = $this->withHeaders([
32+
'Authorization' => 'Bearer '.$token,
33+
])->getJson('/api/licenses/NON-EXISTENT-KEY');
34+
35+
$response->assertStatus(404);
36+
}
37+
38+
public function test_returns_license_with_user_email()
39+
{
40+
$user = User::factory()->create([
41+
'email' => '[email protected]',
42+
'name' => 'Test User',
43+
]);
44+
45+
$license = License::factory()->create([
46+
'user_id' => $user->id,
47+
'key' => 'TEST-LICENSE-KEY-123',
48+
'policy_name' => 'pro',
49+
'source' => 'bifrost',
50+
'anystack_id' => 'anystack_123',
51+
]);
52+
53+
$token = config('services.bifrost.api_key');
54+
55+
$response = $this->withHeaders([
56+
'Authorization' => 'Bearer '.$token,
57+
])->getJson('/api/licenses/'.$license->key);
58+
59+
$response->assertStatus(200)
60+
->assertJson([
61+
'data' => [
62+
'id' => $license->id,
63+
'anystack_id' => 'anystack_123',
64+
'key' => 'TEST-LICENSE-KEY-123',
65+
'policy_name' => 'pro',
66+
'source' => 'bifrost',
67+
'email' => '[email protected]',
68+
],
69+
])
70+
->assertJsonStructure([
71+
'data' => [
72+
'id',
73+
'anystack_id',
74+
'key',
75+
'policy_name',
76+
'source',
77+
'expires_at',
78+
'created_at',
79+
'updated_at',
80+
'email',
81+
],
82+
]);
83+
}
84+
85+
public function test_returns_correct_license_by_key()
86+
{
87+
$user1 = User::factory()->create(['email' => '[email protected]']);
88+
$user2 = User::factory()->create(['email' => '[email protected]']);
89+
90+
$license1 = License::factory()->create([
91+
'user_id' => $user1->id,
92+
'key' => 'KEY-USER-1',
93+
]);
94+
95+
$license2 = License::factory()->create([
96+
'user_id' => $user2->id,
97+
'key' => 'KEY-USER-2',
98+
]);
99+
100+
$token = config('services.bifrost.api_key');
101+
102+
$response = $this->withHeaders([
103+
'Authorization' => 'Bearer '.$token,
104+
])->getJson('/api/licenses/KEY-USER-2');
105+
106+
$response->assertStatus(200)
107+
->assertJson([
108+
'data' => [
109+
'id' => $license2->id,
110+
'key' => 'KEY-USER-2',
111+
'email' => '[email protected]',
112+
],
113+
]);
114+
}
115+
}

0 commit comments

Comments
 (0)