mirror of
https://github.com/usetrmnl/larapaper.git
synced 2026-08-13 14:28:54 -07:00
feat: add trmnlp-compatible plugin settings API endpoints
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
committed by
Benjamin Nussbaum
co-authored by
Claude Sonnet 4.6
parent
1a11a360da
commit
7b7bee1dfa
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Plugin;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
class PluginSettingsController extends Controller
|
||||
{
|
||||
public function me(Request $request): JsonResponse
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'name' => $user->name,
|
||||
'email' => $user->email,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$plugins = Plugin::where('user_id', $request->user()->id)
|
||||
->orderBy('name')
|
||||
->get()
|
||||
->map(fn (Plugin $plugin) => [
|
||||
'id' => $plugin->trmnlp_id,
|
||||
'name' => $plugin->name,
|
||||
'plugin_id' => null,
|
||||
]);
|
||||
|
||||
return response()->json($plugins);
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$plugin = Plugin::create([
|
||||
'user_id' => $request->user()->id,
|
||||
'trmnlp_id' => (string) Uuid::v7(),
|
||||
'name' => 'New TRMNLP Plugin',
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'id' => $plugin->trmnlp_id,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function destroy(Request $request, string $trmnlp_id): Response
|
||||
{
|
||||
Plugin::where('trmnlp_id', $trmnlp_id)
|
||||
->where('user_id', $request->user()->id)
|
||||
->firstOrFail()
|
||||
->delete();
|
||||
|
||||
return response()->noContent();
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ use App\Http\Controllers\Api\Firmware\ScreenController;
|
||||
use App\Http\Controllers\Api\Firmware\SetupController;
|
||||
use App\Http\Controllers\Api\PluginActionController;
|
||||
use App\Http\Controllers\Api\PluginArchiveController;
|
||||
use App\Http\Controllers\Api\PluginSettingsController;
|
||||
use App\Http\Controllers\Api\PluginWebhookController;
|
||||
use App\Http\Controllers\Api\UserController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
@@ -46,6 +47,11 @@ Route::middleware('auth:sanctum')->group(function () {
|
||||
|
||||
Route::get('/plugin_settings/{trmnlp_id}/archive', [PluginArchiveController::class, 'export']);
|
||||
Route::post('/plugin_settings/{trmnlp_id}/archive', [PluginArchiveController::class, 'import']);
|
||||
|
||||
Route::get('/me', [PluginSettingsController::class, 'me']);
|
||||
Route::get('/plugin_settings', [PluginSettingsController::class, 'index']);
|
||||
Route::post('/plugin_settings', [PluginSettingsController::class, 'store']);
|
||||
Route::delete('/plugin_settings/{trmnlp_id}', [PluginSettingsController::class, 'destroy']);
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Models\Plugin;
|
||||
use App\Models\User;
|
||||
use Laravel\Sanctum\Sanctum;
|
||||
|
||||
it('GET /api/me returns name and email for authenticated user', function (): void {
|
||||
$user = User::factory()->create(['name' => 'Bluey', 'email' => 'bluey@example.com']);
|
||||
Sanctum::actingAs($user);
|
||||
|
||||
$response = $this->getJson('/api/me');
|
||||
|
||||
$response->assertOk();
|
||||
$response->assertJson(['data' => ['name' => 'Bluey', 'email' => 'bluey@example.com']]);
|
||||
});
|
||||
|
||||
it('GET /api/me returns 401 when unauthenticated', function (): void {
|
||||
$this->getJson('/api/me')->assertUnauthorized();
|
||||
});
|
||||
|
||||
it('GET /api/plugin_settings returns all user plugins with null plugin_id', function (): void {
|
||||
$user = User::factory()->create();
|
||||
Sanctum::actingAs($user);
|
||||
|
||||
Plugin::factory()->create(['user_id' => $user->id, 'name' => 'Alpha', 'trmnlp_id' => 'uuid-1']);
|
||||
Plugin::factory()->create(['user_id' => $user->id, 'name' => 'Beta', 'trmnlp_id' => 'uuid-2']);
|
||||
|
||||
$otherUser = User::factory()->create();
|
||||
Plugin::factory()->create(['user_id' => $otherUser->id, 'name' => 'Other']);
|
||||
|
||||
$response = $this->getJson('/api/plugin_settings');
|
||||
|
||||
$response->assertOk();
|
||||
$data = $response->json();
|
||||
expect($data)->toHaveCount(2);
|
||||
expect($data[0])->toMatchArray(['id' => 'uuid-1', 'name' => 'Alpha', 'plugin_id' => null]);
|
||||
expect($data[1])->toMatchArray(['id' => 'uuid-2', 'name' => 'Beta', 'plugin_id' => null]);
|
||||
});
|
||||
|
||||
it('GET /api/plugin_settings returns 401 when unauthenticated', function (): void {
|
||||
$this->getJson('/api/plugin_settings')->assertUnauthorized();
|
||||
});
|
||||
|
||||
it('POST /api/plugin_settings creates a blank plugin and returns its trmnlp_id', function (): void {
|
||||
$user = User::factory()->create();
|
||||
Sanctum::actingAs($user);
|
||||
|
||||
$response = $this->postJson('/api/plugin_settings', [
|
||||
'name' => 'New TRMNLP Plugin',
|
||||
'plugin_id' => 37,
|
||||
]);
|
||||
|
||||
$response->assertOk();
|
||||
$id = $response->json('data.id');
|
||||
expect($id)->not->toBeNull();
|
||||
|
||||
$plugin = Plugin::where('trmnlp_id', $id)->where('user_id', $user->id)->first();
|
||||
expect($plugin)->not->toBeNull();
|
||||
});
|
||||
|
||||
it('POST /api/plugin_settings returns 401 when unauthenticated', function (): void {
|
||||
$this->postJson('/api/plugin_settings')->assertUnauthorized();
|
||||
});
|
||||
|
||||
it('DELETE /api/plugin_settings/{trmnlp_id} deletes the plugin and returns 204', function (): void {
|
||||
$user = User::factory()->create();
|
||||
Sanctum::actingAs($user);
|
||||
|
||||
$plugin = Plugin::factory()->create(['user_id' => $user->id, 'trmnlp_id' => 'uuid-del']);
|
||||
|
||||
$response = $this->deleteJson('/api/plugin_settings/uuid-del');
|
||||
|
||||
$response->assertNoContent();
|
||||
expect(Plugin::find($plugin->id))->toBeNull();
|
||||
});
|
||||
|
||||
it('DELETE /api/plugin_settings/{trmnlp_id} returns 404 for unknown id', function (): void {
|
||||
$user = User::factory()->create();
|
||||
Sanctum::actingAs($user);
|
||||
|
||||
$this->deleteJson('/api/plugin_settings/nonexistent-uuid')->assertNotFound();
|
||||
});
|
||||
|
||||
it('DELETE /api/plugin_settings/{trmnlp_id} returns 401 when unauthenticated', function (): void {
|
||||
$this->deleteJson('/api/plugin_settings/any-uuid')->assertUnauthorized();
|
||||
});
|
||||
Reference in New Issue
Block a user