From 5c24b6fbe082f39b7282d4a20d874bafd2f276f1 Mon Sep 17 00:00:00 2001 From: Doar Mihai Date: Sat, 18 Jul 2026 15:25:56 +0300 Subject: [PATCH] feat: add read-only Social Accounts API Add GET /api/accounts (list with optional ?network= and ?type= filters) and GET /api/accounts/{socialAccount} (show) endpoints. Include plain-text password field for AI agent consumption. Co-Authored-By: Claude Sonnet 5 --- .../Api/SocialAccountController.php | 31 +++++++++++++ app/Http/Resources/SocialAccountResource.php | 23 ++++++++++ routes/api.php | 4 ++ tests/Feature/Api/SocialAccountsApiTest.php | 46 +++++++++++++++++++ 4 files changed, 104 insertions(+) create mode 100644 app/Http/Controllers/Api/SocialAccountController.php create mode 100644 app/Http/Resources/SocialAccountResource.php create mode 100644 tests/Feature/Api/SocialAccountsApiTest.php diff --git a/app/Http/Controllers/Api/SocialAccountController.php b/app/Http/Controllers/Api/SocialAccountController.php new file mode 100644 index 0000000..3e271b0 --- /dev/null +++ b/app/Http/Controllers/Api/SocialAccountController.php @@ -0,0 +1,31 @@ +filled('network')) { + $query->where('network', $request->string('network')); + } + + if ($request->filled('type')) { + $query->where('type', $request->string('type')); + } + + return SocialAccountResource::collection($query->orderBy('username')->get()); + } + + public function show(SocialAccount $socialAccount) + { + return new SocialAccountResource($socialAccount); + } +} diff --git a/app/Http/Resources/SocialAccountResource.php b/app/Http/Resources/SocialAccountResource.php new file mode 100644 index 0000000..1b8d380 --- /dev/null +++ b/app/Http/Resources/SocialAccountResource.php @@ -0,0 +1,23 @@ + $this->id, + 'network' => $this->network, + 'username' => $this->username, + 'email' => $this->email, + 'password' => $this->password, + 'type' => $this->type, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/routes/api.php b/routes/api.php index b46f038..805fcca 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,7 +1,11 @@ count(3)->create(); + + $response = $this->getJson('/api/accounts'); + + $response->assertOk()->assertJsonCount(3, 'data'); + expect($response->json('data.0'))->toHaveKey('password'); +}); + +test('it filters accounts by network', function () { + SocialAccount::factory()->create(['network' => 'twitter']); + SocialAccount::factory()->create(['network' => 'instagram']); + + $response = $this->getJson('/api/accounts?network=twitter'); + + $response->assertOk() + ->assertJsonCount(1, 'data') + ->assertJsonPath('data.0.network', 'twitter'); +}); + +test('it filters accounts by type', function () { + SocialAccount::factory()->create(['type' => 'post']); + SocialAccount::factory()->create(['type' => 'like']); + + $response = $this->getJson('/api/accounts?type=post'); + + $response->assertOk() + ->assertJsonCount(1, 'data') + ->assertJsonPath('data.0.type', 'post'); +}); + +test('it shows a single account with password', function () { + $account = SocialAccount::factory()->create(['password' => 'super-secret']); + + $response = $this->getJson("/api/accounts/{$account->id}"); + + $response->assertOk()->assertJsonPath('data.password', 'super-secret'); +}); + +test('it returns 404 for a missing account', function () { + $this->getJson('/api/accounts/999')->assertNotFound(); +});