Release v1.1.0 #79
14 changed files with 239 additions and 176 deletions
|
|
@ -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,9 +19,10 @@ 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.');
|
||||
}
|
||||
|
||||
return DB::transaction(function () use ($name, $platformInstanceId, $languageId, $description, $activeAccounts) {
|
||||
$channel = PlatformChannel::create([
|
||||
'platform_instance_id' => $platformInstanceId,
|
||||
'channel_id' => $name,
|
||||
|
|
@ -38,5 +41,6 @@ public function execute(string $name, int $platformInstanceId, ?int $languageId
|
|||
]);
|
||||
|
||||
return $channel->load('platformAccounts');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}");
|
||||
|
|
|
|||
|
|
@ -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,6 +24,7 @@ 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);
|
||||
|
||||
return DB::transaction(function () use ($fullInstanceUrl, $instanceDomain, $username, $password, $platform, $authResponse) {
|
||||
$platformInstance = PlatformInstance::firstOrCreate([
|
||||
'url' => $fullInstanceUrl,
|
||||
'platform' => $platform,
|
||||
|
|
@ -46,5 +48,6 @@ public function execute(string $instanceDomain, string $username, string $passwo
|
|||
'is_active' => true,
|
||||
'status' => 'active',
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = $createChannelAction->execute(
|
||||
$validated['name'],
|
||||
$validated['platform_instance_id'],
|
||||
$validated['language_id'] ?? null,
|
||||
$validated['description'] ?? null,
|
||||
);
|
||||
}
|
||||
|
||||
$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(),
|
||||
]);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
36
app/Http/Requests/StorePlatformAccountRequest.php
Normal file
36
app/Http/Requests/StorePlatformAccountRequest.php
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StorePlatformAccountRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
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<string, string>
|
||||
*/
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'instance_url.regex' => 'Please enter a valid domain name (e.g., lemmy.world, belgae.social)',
|
||||
];
|
||||
}
|
||||
}
|
||||
26
app/Http/Requests/StorePlatformChannelRequest.php
Normal file
26
app/Http/Requests/StorePlatformChannelRequest.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StorePlatformChannelRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
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',
|
||||
];
|
||||
}
|
||||
}
|
||||
26
app/Http/Requests/StoreRouteRequest.php
Normal file
26
app/Http/Requests/StoreRouteRequest.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreRouteRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
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',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -49,7 +49,7 @@ 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',
|
||||
|
|
@ -81,7 +81,7 @@ 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',
|
||||
|
|
@ -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,13 +107,13 @@ 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',
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
|
|
|||
Loading…
Reference in a new issue