Release v1.1.0 #79

Merged
myrmidex merged 12 commits from release/v1.1.0 into main 2026-03-08 11:44:53 +01:00
7 changed files with 38 additions and 17 deletions
Showing only changes of commit 58b07830ec - Show all commits

View file

@ -33,6 +33,7 @@ public function execute(string $name, int $platformInstanceId, ?int $languageId
'is_active' => true, 'is_active' => true,
]); ]);
// Attach only the first active account — additional accounts can be linked via the channel management UI
$channel->platformAccounts()->attach($activeAccounts->first()->id, [ $channel->platformAccounts()->attach($activeAccounts->first()->id, [
'is_active' => true, 'is_active' => true,
'priority' => 1, 'priority' => 1,

View file

@ -6,13 +6,21 @@
class CreateRouteAction class CreateRouteAction
{ {
/**
* Create a route or return an existing one for the same feed+channel pair.
* When a route already exists, the provided priority and isActive values are ignored.
*/
public function execute(int $feedId, int $platformChannelId, int $priority = 0, bool $isActive = true): Route public function execute(int $feedId, int $platformChannelId, int $priority = 0, bool $isActive = true): Route
{ {
return Route::create([ return Route::firstOrCreate(
[
'feed_id' => $feedId, 'feed_id' => $feedId,
'platform_channel_id' => $platformChannelId, 'platform_channel_id' => $platformChannelId,
],
[
'priority' => $priority, 'priority' => $priority,
'is_active' => $isActive, 'is_active' => $isActive,
]); ]
);
} }
} }

View file

@ -14,9 +14,6 @@
class PlatformAccountsController extends BaseController class PlatformAccountsController extends BaseController
{ {
public function __construct(
private readonly CreatePlatformAccountAction $createPlatformAccountAction,
) {}
/** /**
* Display a listing of platform accounts * Display a listing of platform accounts
*/ */
@ -35,13 +32,13 @@ public function index(): JsonResponse
/** /**
* Store a newly created platform account * Store a newly created platform account
*/ */
public function store(StorePlatformAccountRequest $request): JsonResponse public function store(StorePlatformAccountRequest $request, CreatePlatformAccountAction $action): JsonResponse
{ {
try { try {
$validated = $request->validated(); $validated = $request->validated();
$account = $this->createPlatformAccountAction->execute( $account = $action->execute(
$validated['instance_url'], $validated['instance_domain'],
$validated['username'], $validated['username'],
$validated['password'], $validated['password'],
$validated['platform'], $validated['platform'],

View file

@ -18,7 +18,7 @@ public function rules(): array
{ {
return [ return [
'platform' => 'required|in:lemmy', 'platform' => 'required|in:lemmy',
'instance_url' => 'required|string|max:255|regex:/^[a-zA-Z0-9]([a-zA-Z0-9\-\.]*[a-zA-Z0-9])?$/', 'instance_domain' => 'required|string|max:255|regex:/^[a-zA-Z0-9]([a-zA-Z0-9\-\.]*[a-zA-Z0-9])?$/',
'username' => 'required|string|max:255', 'username' => 'required|string|max:255',
'password' => 'required|string', 'password' => 'required|string',
]; ];
@ -30,7 +30,7 @@ public function rules(): array
public function messages(): array public function messages(): array
{ {
return [ return [
'instance_url.regex' => 'Please enter a valid domain name (e.g., lemmy.world, belgae.social)', 'instance_domain.regex' => 'Please enter a valid domain name (e.g., lemmy.world, belgae.social)',
]; ];
} }
} }

View file

@ -53,7 +53,8 @@ class Onboarding extends Component
// State // State
public array $formErrors = []; public array $formErrors = [];
public bool $isLoading = false; public bool $isLoading = false;
private ?int $previousChannelLanguageId = null; #[\Livewire\Attributes\Locked]
public ?int $previousChannelLanguageId = null;
protected CreatePlatformAccountAction $createPlatformAccountAction; protected CreatePlatformAccountAction $createPlatformAccountAction;
protected CreateFeedAction $createFeedAction; protected CreateFeedAction $createFeedAction;

View file

@ -56,7 +56,7 @@ public function test_store_creates_platform_account_successfully(): void
$data = [ $data = [
'platform' => 'lemmy', 'platform' => 'lemmy',
'instance_url' => 'lemmy.example.com', 'instance_domain' => 'lemmy.example.com',
'username' => 'testuser', 'username' => 'testuser',
'password' => 'testpass123', 'password' => 'testpass123',
]; ];
@ -94,7 +94,7 @@ public function test_store_validates_required_fields(): void
$response = $this->postJson('/api/v1/platform-accounts', []); $response = $this->postJson('/api/v1/platform-accounts', []);
$response->assertStatus(422) $response->assertStatus(422)
->assertJsonValidationErrors(['platform', 'instance_url', 'username', 'password']); ->assertJsonValidationErrors(['platform', 'instance_domain', 'username', 'password']);
} }
public function test_show_returns_platform_account_successfully(): void public function test_show_returns_platform_account_successfully(): void

View file

@ -59,4 +59,18 @@ public function test_creates_inactive_route(): void
$this->assertFalse($route->is_active); $this->assertFalse($route->is_active);
} }
public function test_returns_existing_route_for_duplicate_feed_channel_pair(): void
{
$language = Language::factory()->create();
$feed = Feed::factory()->language($language)->create();
$channel = PlatformChannel::factory()->create();
$first = $this->action->execute($feed->id, $channel->id, 10);
$second = $this->action->execute($feed->id, $channel->id, 99);
$this->assertEquals($first->id, $second->id);
$this->assertEquals(10, $second->priority);
$this->assertDatabaseCount('routes', 1);
}
} }