From 025794c8528467f3390e583b73b8b5a792c8b206 Mon Sep 17 00:00:00 2001 From: myrmidex Date: Sun, 8 Mar 2026 01:42:21 +0100 Subject: [PATCH] 61 - Refactor model controllers to use Actions and FormRequests --- app/Actions/CreateChannelAction.php | 38 ++++++----- app/Actions/CreateFeedAction.php | 3 +- app/Actions/CreatePlatformAccountAction.php | 47 +++++++------ .../Controllers/Api/V1/FeedsController.php | 35 +++++----- .../Api/V1/PlatformAccountsController.php | 61 +++++++---------- .../Api/V1/PlatformChannelsController.php | 67 ++++++------------- .../Controllers/Api/V1/RoutingController.php | 32 +++++---- .../Requests/StorePlatformAccountRequest.php | 36 ++++++++++ .../Requests/StorePlatformChannelRequest.php | 26 +++++++ app/Http/Requests/StoreRouteRequest.php | 26 +++++++ .../Api/V1/FeedsControllerTest.php | 16 ++--- .../Api/V1/PlatformAccountsControllerTest.php | 15 ++++- .../Api/V1/PlatformChannelsControllerTest.php | 10 +-- .../CreatePlatformAccountActionTest.php | 3 +- 14 files changed, 239 insertions(+), 176 deletions(-) create mode 100644 app/Http/Requests/StorePlatformAccountRequest.php create mode 100644 app/Http/Requests/StorePlatformChannelRequest.php create mode 100644 app/Http/Requests/StoreRouteRequest.php diff --git a/app/Actions/CreateChannelAction.php b/app/Actions/CreateChannelAction.php index 4f99eeb..3d72ae0 100644 --- a/app/Actions/CreateChannelAction.php +++ b/app/Actions/CreateChannelAction.php @@ -5,6 +5,8 @@ use App\Models\PlatformAccount; use App\Models\PlatformChannel; use App\Models\PlatformInstance; +use Illuminate\Support\Facades\DB; +use RuntimeException; class CreateChannelAction { @@ -17,26 +19,28 @@ public function execute(string $name, int $platformInstanceId, ?int $languageId ->get(); if ($activeAccounts->isEmpty()) { - throw new \RuntimeException('No active platform accounts found for this instance. Please create a platform account first.'); + throw new RuntimeException('No active platform accounts found for this instance. Please create a platform account first.'); } - $channel = PlatformChannel::create([ - 'platform_instance_id' => $platformInstanceId, - 'channel_id' => $name, - 'name' => $name, - 'display_name' => ucfirst($name), - 'description' => $description, - 'language_id' => $languageId, - 'is_active' => true, - ]); + return DB::transaction(function () use ($name, $platformInstanceId, $languageId, $description, $activeAccounts) { + $channel = PlatformChannel::create([ + 'platform_instance_id' => $platformInstanceId, + 'channel_id' => $name, + 'name' => $name, + 'display_name' => ucfirst($name), + 'description' => $description, + 'language_id' => $languageId, + 'is_active' => true, + ]); - $channel->platformAccounts()->attach($activeAccounts->first()->id, [ - 'is_active' => true, - 'priority' => 1, - 'created_at' => now(), - 'updated_at' => now(), - ]); + $channel->platformAccounts()->attach($activeAccounts->first()->id, [ + 'is_active' => true, + 'priority' => 1, + 'created_at' => now(), + 'updated_at' => now(), + ]); - return $channel->load('platformAccounts'); + return $channel->load('platformAccounts'); + }); } } diff --git a/app/Actions/CreateFeedAction.php b/app/Actions/CreateFeedAction.php index 457b75f..ac3ac62 100644 --- a/app/Actions/CreateFeedAction.php +++ b/app/Actions/CreateFeedAction.php @@ -4,6 +4,7 @@ use App\Models\Feed; use App\Models\Language; +use InvalidArgumentException; class CreateFeedAction { @@ -15,7 +16,7 @@ public function execute(string $name, string $provider, int $languageId, ?string $url = config("feed.providers.{$provider}.languages.{$langCode}.url"); if (!$url) { - throw new \InvalidArgumentException("Invalid provider and language combination: {$provider}/{$langCode}"); + throw new InvalidArgumentException("Invalid provider and language combination: {$provider}/{$langCode}"); } $providerConfig = config("feed.providers.{$provider}"); diff --git a/app/Actions/CreatePlatformAccountAction.php b/app/Actions/CreatePlatformAccountAction.php index f40b3c3..e84e37d 100644 --- a/app/Actions/CreatePlatformAccountAction.php +++ b/app/Actions/CreatePlatformAccountAction.php @@ -6,6 +6,7 @@ use App\Models\PlatformAccount; use App\Models\PlatformInstance; use App\Services\Auth\LemmyAuthService; +use Illuminate\Support\Facades\DB; class CreatePlatformAccountAction { @@ -23,28 +24,30 @@ public function execute(string $instanceDomain, string $username, string $passwo // Authenticate first — if this fails, no records are created $authResponse = $this->lemmyAuthService->authenticate($fullInstanceUrl, $username, $password); - $platformInstance = PlatformInstance::firstOrCreate([ - 'url' => $fullInstanceUrl, - 'platform' => $platform, - ], [ - 'name' => ucfirst($instanceDomain), - 'is_active' => true, - ]); + return DB::transaction(function () use ($fullInstanceUrl, $instanceDomain, $username, $password, $platform, $authResponse) { + $platformInstance = PlatformInstance::firstOrCreate([ + 'url' => $fullInstanceUrl, + 'platform' => $platform, + ], [ + 'name' => ucfirst($instanceDomain), + 'is_active' => true, + ]); - return PlatformAccount::create([ - 'platform' => $platform, - 'instance_url' => $fullInstanceUrl, - 'username' => $username, - 'password' => $password, - 'settings' => [ - 'display_name' => $authResponse['person_view']['person']['display_name'] ?? null, - 'description' => $authResponse['person_view']['person']['bio'] ?? null, - 'person_id' => $authResponse['person_view']['person']['id'] ?? null, - 'platform_instance_id' => $platformInstance->id, - 'api_token' => $authResponse['jwt'] ?? null, - ], - 'is_active' => true, - 'status' => 'active', - ]); + return PlatformAccount::create([ + 'platform' => $platform, + 'instance_url' => $fullInstanceUrl, + 'username' => $username, + 'password' => $password, + 'settings' => [ + 'display_name' => $authResponse['person_view']['person']['display_name'] ?? null, + 'description' => $authResponse['person_view']['person']['bio'] ?? null, + 'person_id' => $authResponse['person_view']['person']['id'] ?? null, + 'platform_instance_id' => $platformInstance->id, + 'api_token' => $authResponse['jwt'] ?? null, + ], + 'is_active' => true, + 'status' => 'active', + ]); + }); } } diff --git a/app/Http/Controllers/Api/V1/FeedsController.php b/app/Http/Controllers/Api/V1/FeedsController.php index f8b07f0..37f8bf1 100644 --- a/app/Http/Controllers/Api/V1/FeedsController.php +++ b/app/Http/Controllers/Api/V1/FeedsController.php @@ -2,12 +2,15 @@ namespace App\Http\Controllers\Api\V1; +use App\Actions\CreateFeedAction; use App\Http\Requests\StoreFeedRequest; use App\Http\Requests\UpdateFeedRequest; use App\Http\Resources\FeedResource; use App\Models\Feed; +use Exception; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use InvalidArgumentException; use Illuminate\Validation\ValidationException; class FeedsController extends BaseController @@ -41,32 +44,26 @@ public function index(Request $request): JsonResponse /** * Store a newly created feed */ - public function store(StoreFeedRequest $request): JsonResponse + public function store(StoreFeedRequest $request, CreateFeedAction $createFeedAction): JsonResponse { try { $validated = $request->validated(); - $validated['is_active'] = $validated['is_active'] ?? true; - // Map provider to URL and set type - $providers = [ - 'vrt' => new \App\Services\Parsers\VrtHomepageParserAdapter(), - 'belga' => new \App\Services\Parsers\BelgaHomepageParserAdapter(), - ]; - - $adapter = $providers[$validated['provider']]; - $validated['url'] = $adapter->getHomepageUrl(); - $validated['type'] = 'website'; - - $feed = Feed::create($validated); + $feed = $createFeedAction->execute( + $validated['name'], + $validated['provider'], + $validated['language_id'], + $validated['description'] ?? null, + ); return $this->sendResponse( new FeedResource($feed), 'Feed created successfully!', 201 ); - } catch (ValidationException $e) { - return $this->sendValidationError($e->errors()); - } catch (\Exception $e) { + } catch (InvalidArgumentException $e) { + return $this->sendError($e->getMessage(), [], 422); + } catch (Exception $e) { return $this->sendError('Failed to create feed: ' . $e->getMessage(), [], 500); } } @@ -99,7 +96,7 @@ public function update(UpdateFeedRequest $request, Feed $feed): JsonResponse ); } catch (ValidationException $e) { return $this->sendValidationError($e->errors()); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to update feed: ' . $e->getMessage(), [], 500); } } @@ -116,7 +113,7 @@ public function destroy(Feed $feed): JsonResponse null, 'Feed deleted successfully!' ); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to delete feed: ' . $e->getMessage(), [], 500); } } @@ -136,7 +133,7 @@ public function toggle(Feed $feed): JsonResponse new FeedResource($feed->fresh()), "Feed {$status} successfully!" ); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to toggle feed status: ' . $e->getMessage(), [], 500); } } diff --git a/app/Http/Controllers/Api/V1/PlatformAccountsController.php b/app/Http/Controllers/Api/V1/PlatformAccountsController.php index f9b3a58..61ea6fa 100644 --- a/app/Http/Controllers/Api/V1/PlatformAccountsController.php +++ b/app/Http/Controllers/Api/V1/PlatformAccountsController.php @@ -2,16 +2,21 @@ namespace App\Http\Controllers\Api\V1; -use App\Enums\PlatformEnum; +use App\Actions\CreatePlatformAccountAction; +use App\Exceptions\PlatformAuthException; +use App\Http\Requests\StorePlatformAccountRequest; use App\Http\Resources\PlatformAccountResource; use App\Models\PlatformAccount; -use App\Models\PlatformInstance; +use Exception; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Validation\ValidationException; class PlatformAccountsController extends BaseController { + public function __construct( + private readonly CreatePlatformAccountAction $createPlatformAccountAction, + ) {} /** * Display a listing of platform accounts */ @@ -30,46 +35,30 @@ public function index(): JsonResponse /** * Store a newly created platform account */ - public function store(Request $request): JsonResponse + public function store(StorePlatformAccountRequest $request): JsonResponse { try { - $validated = $request->validate([ - 'platform' => 'required|in:lemmy,mastodon,reddit', - 'instance_url' => 'required|url', - 'username' => 'required|string|max:255', - 'password' => 'required|string', - 'settings' => 'nullable|array', - ]); + $validated = $request->validated(); - // Create or find platform instance - $platformEnum = PlatformEnum::from($validated['platform']); - $instance = PlatformInstance::firstOrCreate([ - 'platform' => $platformEnum, - 'url' => $validated['instance_url'], - ], [ - 'name' => parse_url($validated['instance_url'], PHP_URL_HOST), - 'description' => ucfirst($validated['platform']) . ' instance', - 'is_active' => true, - ]); - - $account = PlatformAccount::create($validated); - - // If this is the first account for this platform, make it active - if (!PlatformAccount::where('platform', $validated['platform']) - ->where('is_active', true) - ->exists()) { - $account->setAsActive(); - } + $account = $this->createPlatformAccountAction->execute( + $validated['instance_url'], + $validated['username'], + $validated['password'], + $validated['platform'], + ); return $this->sendResponse( new PlatformAccountResource($account), 'Platform account created successfully!', 201 ); - } catch (ValidationException $e) { - return $this->sendValidationError($e->errors()); - } catch (\Exception $e) { - return $this->sendError('Failed to create platform account: ' . $e->getMessage(), [], 500); + } catch (PlatformAuthException $e) { + if (str_contains($e->getMessage(), 'Rate limited by')) { + return $this->sendError($e->getMessage(), [], 429); + } + return $this->sendError('Invalid username or password. Please check your credentials and try again.', [], 422); + } catch (Exception $e) { + return $this->sendError('Unable to connect to the Lemmy instance. Please check the URL and try again.', [], 422); } } @@ -110,7 +99,7 @@ public function update(Request $request, PlatformAccount $platformAccount): Json ); } catch (ValidationException $e) { return $this->sendValidationError($e->errors()); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to update platform account: ' . $e->getMessage(), [], 500); } } @@ -127,7 +116,7 @@ public function destroy(PlatformAccount $platformAccount): JsonResponse null, 'Platform account deleted successfully!' ); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to delete platform account: ' . $e->getMessage(), [], 500); } } @@ -144,7 +133,7 @@ public function setActive(PlatformAccount $platformAccount): JsonResponse new PlatformAccountResource($platformAccount->fresh()), "Set {$platformAccount->username}@{$platformAccount->instance_url} as active for {$platformAccount->platform->value}!" ); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to set platform account as active: ' . $e->getMessage(), [], 500); } } diff --git a/app/Http/Controllers/Api/V1/PlatformChannelsController.php b/app/Http/Controllers/Api/V1/PlatformChannelsController.php index 9e7fcfa..8f94aec 100644 --- a/app/Http/Controllers/Api/V1/PlatformChannelsController.php +++ b/app/Http/Controllers/Api/V1/PlatformChannelsController.php @@ -2,12 +2,16 @@ namespace App\Http\Controllers\Api\V1; +use App\Actions\CreateChannelAction; +use App\Http\Requests\StorePlatformChannelRequest; use App\Http\Resources\PlatformChannelResource; use App\Models\PlatformChannel; use App\Models\PlatformAccount; +use Exception; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Validation\ValidationException; +use RuntimeException; class PlatformChannelsController extends BaseController { @@ -30,55 +34,26 @@ public function index(): JsonResponse /** * Store a newly created platform channel */ - public function store(Request $request): JsonResponse + public function store(StorePlatformChannelRequest $request, CreateChannelAction $createChannelAction): JsonResponse { try { - $validated = $request->validate([ - 'platform_instance_id' => 'required|exists:platform_instances,id', - 'channel_id' => 'required|string|max:255', - 'name' => 'required|string|max:255', - 'display_name' => 'nullable|string|max:255', - 'description' => 'nullable|string', - 'is_active' => 'boolean', - ]); + $validated = $request->validated(); - $validated['is_active'] = $validated['is_active'] ?? true; - - // Get the platform instance to check for active accounts - $platformInstance = \App\Models\PlatformInstance::findOrFail($validated['platform_instance_id']); - - // Check if there are active platform accounts for this instance - $activeAccounts = PlatformAccount::where('instance_url', $platformInstance->url) - ->where('is_active', true) - ->get(); - - if ($activeAccounts->isEmpty()) { - return $this->sendError( - 'Cannot create channel: No active platform accounts found for this instance. Please create a platform account first.', - [], - 422 - ); - } - - $channel = PlatformChannel::create($validated); - - // Automatically attach the first active account to the channel - $firstAccount = $activeAccounts->first(); - $channel->platformAccounts()->attach($firstAccount->id, [ - 'is_active' => true, - 'priority' => 1, - 'created_at' => now(), - 'updated_at' => now(), - ]); + $channel = $createChannelAction->execute( + $validated['name'], + $validated['platform_instance_id'], + $validated['language_id'] ?? null, + $validated['description'] ?? null, + ); return $this->sendResponse( new PlatformChannelResource($channel->load(['platformInstance', 'platformAccounts'])), 'Platform channel created successfully and linked to platform account!', 201 ); - } catch (ValidationException $e) { - return $this->sendValidationError($e->errors()); - } catch (\Exception $e) { + } catch (RuntimeException $e) { + return $this->sendError($e->getMessage(), [], 422); + } catch (Exception $e) { return $this->sendError('Failed to create platform channel: ' . $e->getMessage(), [], 500); } } @@ -115,7 +90,7 @@ public function update(Request $request, PlatformChannel $platformChannel): Json ); } catch (ValidationException $e) { return $this->sendValidationError($e->errors()); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to update platform channel: ' . $e->getMessage(), [], 500); } } @@ -132,7 +107,7 @@ public function destroy(PlatformChannel $platformChannel): JsonResponse null, 'Platform channel deleted successfully!' ); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to delete platform channel: ' . $e->getMessage(), [], 500); } } @@ -152,7 +127,7 @@ public function toggle(PlatformChannel $channel): JsonResponse new PlatformChannelResource($channel->fresh(['platformInstance', 'platformAccounts'])), "Platform channel {$status} successfully!" ); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to toggle platform channel status: ' . $e->getMessage(), [], 500); } } @@ -189,7 +164,7 @@ public function attachAccount(PlatformChannel $channel, Request $request): JsonR ); } catch (ValidationException $e) { return $this->sendValidationError($e->errors()); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to attach platform account: ' . $e->getMessage(), [], 500); } } @@ -210,7 +185,7 @@ public function detachAccount(PlatformChannel $channel, PlatformAccount $account new PlatformChannelResource($channel->fresh(['platformInstance', 'platformAccounts'])), 'Platform account detached from channel successfully!' ); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to detach platform account: ' . $e->getMessage(), [], 500); } } @@ -242,7 +217,7 @@ public function updateAccountRelation(PlatformChannel $channel, PlatformAccount ); } catch (ValidationException $e) { return $this->sendValidationError($e->errors()); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to update platform account relationship: ' . $e->getMessage(), [], 500); } } diff --git a/app/Http/Controllers/Api/V1/RoutingController.php b/app/Http/Controllers/Api/V1/RoutingController.php index 1693cd8..185f099 100644 --- a/app/Http/Controllers/Api/V1/RoutingController.php +++ b/app/Http/Controllers/Api/V1/RoutingController.php @@ -2,10 +2,13 @@ namespace App\Http\Controllers\Api\V1; +use App\Actions\CreateRouteAction; +use App\Http\Requests\StoreRouteRequest; use App\Http\Resources\RouteResource; use App\Models\Feed; use App\Models\PlatformChannel; use App\Models\Route; +use Exception; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Validation\ValidationException; @@ -31,29 +34,24 @@ public function index(): JsonResponse /** * Store a newly created routing configuration */ - public function store(Request $request): JsonResponse + public function store(StoreRouteRequest $request, CreateRouteAction $createRouteAction): JsonResponse { try { - $validated = $request->validate([ - 'feed_id' => 'required|exists:feeds,id', - 'platform_channel_id' => 'required|exists:platform_channels,id', - 'is_active' => 'boolean', - 'priority' => 'nullable|integer|min:0', - ]); + $validated = $request->validated(); - $validated['is_active'] = $validated['is_active'] ?? true; - $validated['priority'] = $validated['priority'] ?? 0; - - $route = Route::create($validated); + $route = $createRouteAction->execute( + $validated['feed_id'], + $validated['platform_channel_id'], + $validated['priority'] ?? 0, + $validated['is_active'] ?? true, + ); return $this->sendResponse( new RouteResource($route->load(['feed', 'platformChannel', 'keywords'])), 'Routing configuration created successfully!', 201 ); - } catch (ValidationException $e) { - return $this->sendValidationError($e->errors()); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to create routing configuration: ' . $e->getMessage(), [], 500); } } @@ -104,7 +102,7 @@ public function update(Request $request, Feed $feed, PlatformChannel $channel): ); } catch (ValidationException $e) { return $this->sendValidationError($e->errors()); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to update routing configuration: ' . $e->getMessage(), [], 500); } } @@ -129,7 +127,7 @@ public function destroy(Feed $feed, PlatformChannel $channel): JsonResponse null, 'Routing configuration deleted successfully!' ); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to delete routing configuration: ' . $e->getMessage(), [], 500); } } @@ -157,7 +155,7 @@ public function toggle(Feed $feed, PlatformChannel $channel): JsonResponse new RouteResource($route->fresh(['feed', 'platformChannel', 'keywords'])), "Routing configuration {$status} successfully!" ); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->sendError('Failed to toggle routing configuration status: ' . $e->getMessage(), [], 500); } } diff --git a/app/Http/Requests/StorePlatformAccountRequest.php b/app/Http/Requests/StorePlatformAccountRequest.php new file mode 100644 index 0000000..17dc064 --- /dev/null +++ b/app/Http/Requests/StorePlatformAccountRequest.php @@ -0,0 +1,36 @@ + + */ + public function rules(): array + { + return [ + 'platform' => 'required|in:lemmy', + 'instance_url' => 'required|string|max:255|regex:/^[a-zA-Z0-9]([a-zA-Z0-9\-\.]*[a-zA-Z0-9])?$/', + 'username' => 'required|string|max:255', + 'password' => 'required|string', + ]; + } + + /** + * @return array + */ + public function messages(): array + { + return [ + 'instance_url.regex' => 'Please enter a valid domain name (e.g., lemmy.world, belgae.social)', + ]; + } +} diff --git a/app/Http/Requests/StorePlatformChannelRequest.php b/app/Http/Requests/StorePlatformChannelRequest.php new file mode 100644 index 0000000..0950699 --- /dev/null +++ b/app/Http/Requests/StorePlatformChannelRequest.php @@ -0,0 +1,26 @@ + + */ + public function rules(): array + { + return [ + 'platform_instance_id' => 'required|exists:platform_instances,id', + 'name' => 'required|string|max:255', + 'language_id' => 'nullable|exists:languages,id', + 'description' => 'nullable|string', + ]; + } +} diff --git a/app/Http/Requests/StoreRouteRequest.php b/app/Http/Requests/StoreRouteRequest.php new file mode 100644 index 0000000..572f835 --- /dev/null +++ b/app/Http/Requests/StoreRouteRequest.php @@ -0,0 +1,26 @@ + + */ + public function rules(): array + { + return [ + 'feed_id' => 'required|exists:feeds,id', + 'platform_channel_id' => 'required|exists:platform_channels,id', + 'is_active' => 'boolean', + 'priority' => 'nullable|integer|min:0', + ]; + } +} diff --git a/tests/Feature/Http/Controllers/Api/V1/FeedsControllerTest.php b/tests/Feature/Http/Controllers/Api/V1/FeedsControllerTest.php index 5b53248..25c2695 100644 --- a/tests/Feature/Http/Controllers/Api/V1/FeedsControllerTest.php +++ b/tests/Feature/Http/Controllers/Api/V1/FeedsControllerTest.php @@ -49,8 +49,8 @@ public function test_index_returns_feeds_ordered_by_active_status_then_name(): v public function test_store_creates_vrt_feed_successfully(): void { - $language = Language::factory()->create(); - + $language = Language::factory()->english()->create(); + $feedData = [ 'name' => 'VRT Test Feed', 'provider' => 'vrt', @@ -81,8 +81,8 @@ public function test_store_creates_vrt_feed_successfully(): void public function test_store_creates_belga_feed_successfully(): void { - $language = Language::factory()->create(); - + $language = Language::factory()->english()->create(); + $feedData = [ 'name' => 'Belga Test Feed', 'provider' => 'belga', @@ -99,7 +99,7 @@ public function test_store_creates_belga_feed_successfully(): void 'data' => [ 'name' => 'Belga Test Feed', 'url' => 'https://www.belganewsagency.eu/', - 'type' => 'website', + 'type' => 'rss', 'is_active' => true, ] ]); @@ -107,14 +107,14 @@ public function test_store_creates_belga_feed_successfully(): void $this->assertDatabaseHas('feeds', [ 'name' => 'Belga Test Feed', 'url' => 'https://www.belganewsagency.eu/', - 'type' => 'website', + 'type' => 'rss', ]); } public function test_store_sets_default_active_status(): void { - $language = Language::factory()->create(); - + $language = Language::factory()->english()->create(); + $feedData = [ 'name' => 'Test Feed', 'provider' => 'vrt', diff --git a/tests/Feature/Http/Controllers/Api/V1/PlatformAccountsControllerTest.php b/tests/Feature/Http/Controllers/Api/V1/PlatformAccountsControllerTest.php index ae4573a..b68d9b4 100644 --- a/tests/Feature/Http/Controllers/Api/V1/PlatformAccountsControllerTest.php +++ b/tests/Feature/Http/Controllers/Api/V1/PlatformAccountsControllerTest.php @@ -4,7 +4,9 @@ use App\Models\PlatformAccount; use App\Models\PlatformInstance; +use App\Services\Auth\LemmyAuthService; use Illuminate\Foundation\Testing\RefreshDatabase; +use Mockery; use Tests\TestCase; class PlatformAccountsControllerTest extends TestCase @@ -42,12 +44,21 @@ public function test_index_returns_successful_response(): void public function test_store_creates_platform_account_successfully(): void { + $mockAuth = Mockery::mock(LemmyAuthService::class); + $mockAuth->shouldReceive('authenticate') + ->once() + ->with('https://lemmy.example.com', 'testuser', 'testpass123') + ->andReturn([ + 'jwt' => 'test-token', + 'person_view' => ['person' => ['id' => 1, 'display_name' => null, 'bio' => null]], + ]); + $this->app->instance(LemmyAuthService::class, $mockAuth); + $data = [ 'platform' => 'lemmy', - 'instance_url' => 'https://lemmy.example.com', + 'instance_url' => 'lemmy.example.com', 'username' => 'testuser', 'password' => 'testpass123', - 'settings' => ['key' => 'value'] ]; $response = $this->postJson('/api/v1/platform-accounts', $data); diff --git a/tests/Feature/Http/Controllers/Api/V1/PlatformChannelsControllerTest.php b/tests/Feature/Http/Controllers/Api/V1/PlatformChannelsControllerTest.php index 63765ca..b6e883e 100644 --- a/tests/Feature/Http/Controllers/Api/V1/PlatformChannelsControllerTest.php +++ b/tests/Feature/Http/Controllers/Api/V1/PlatformChannelsControllerTest.php @@ -56,11 +56,8 @@ public function test_store_creates_platform_channel_successfully(): void $data = [ 'platform_instance_id' => $instance->id, - 'channel_id' => 'test_channel', - 'name' => 'Test Channel', - 'display_name' => 'Test Channel Display', + 'name' => 'test_channel', 'description' => 'A test channel', - 'is_active' => true ]; $response = $this->postJson('/api/v1/platform-channels', $data); @@ -89,7 +86,7 @@ public function test_store_creates_platform_channel_successfully(): void $this->assertDatabaseHas('platform_channels', [ 'platform_instance_id' => $instance->id, 'channel_id' => 'test_channel', - 'name' => 'Test Channel', + 'name' => 'test_channel', ]); } @@ -98,14 +95,13 @@ public function test_store_validates_required_fields(): void $response = $this->postJson('/api/v1/platform-channels', []); $response->assertStatus(422) - ->assertJsonValidationErrors(['platform_instance_id', 'channel_id', 'name']); + ->assertJsonValidationErrors(['platform_instance_id', 'name']); } public function test_store_validates_platform_instance_exists(): void { $data = [ 'platform_instance_id' => 999, - 'channel_id' => 'test_channel', 'name' => 'Test Channel' ]; diff --git a/tests/Unit/Actions/CreatePlatformAccountActionTest.php b/tests/Unit/Actions/CreatePlatformAccountActionTest.php index 765e540..5d01af3 100644 --- a/tests/Unit/Actions/CreatePlatformAccountActionTest.php +++ b/tests/Unit/Actions/CreatePlatformAccountActionTest.php @@ -3,6 +3,7 @@ namespace Tests\Unit\Actions; use App\Actions\CreatePlatformAccountAction; +use App\Enums\PlatformEnum; use App\Exceptions\PlatformAuthException; use App\Models\PlatformAccount; use App\Models\PlatformInstance; @@ -89,7 +90,7 @@ public function test_propagates_auth_exception(): void $this->lemmyAuthService ->shouldReceive('authenticate') ->once() - ->andThrow(new PlatformAuthException(\App\Enums\PlatformEnum::LEMMY, 'Invalid credentials')); + ->andThrow(new PlatformAuthException(PlatformEnum::LEMMY, 'Invalid credentials')); try { $this->action->execute('lemmy.world', 'baduser', 'badpass');