assertEquals($fillableFields, $account->getFillable()); } public function test_table_name(): void { $account = new PlatformAccount(); $this->assertEquals('platform_accounts', $account->getTable()); } public function test_casts_platform_to_enum(): void { $account = PlatformAccount::factory()->create(['platform' => PlatformEnum::LEMMY]); $this->assertInstanceOf(PlatformEnum::class, $account->platform); $this->assertEquals(PlatformEnum::LEMMY, $account->platform); $this->assertEquals('lemmy', $account->platform->value); } public function test_casts_settings_to_array(): void { $settings = ['key1' => 'value1', 'nested' => ['key2' => 'value2']]; $account = PlatformAccount::factory()->create(['settings' => $settings]); $this->assertIsArray($account->settings); $this->assertEquals($settings, $account->settings); } public function test_casts_is_active_to_boolean(): void { $account = PlatformAccount::factory()->create(['is_active' => '1']); $this->assertIsBool($account->is_active); $this->assertTrue($account->is_active); $account->update(['is_active' => '0']); $account->refresh(); $this->assertIsBool($account->is_active); $this->assertFalse($account->is_active); } public function test_casts_last_tested_at_to_datetime(): void { $timestamp = now()->subHours(2); $account = PlatformAccount::factory()->create(['last_tested_at' => $timestamp]); $this->assertInstanceOf(\Carbon\Carbon::class, $account->last_tested_at); $this->assertEquals($timestamp->format('Y-m-d H:i:s'), $account->last_tested_at->format('Y-m-d H:i:s')); } public function test_password_encryption_and_decryption(): void { $plainPassword = 'my-secret-password'; $account = PlatformAccount::factory()->create(['password' => $plainPassword]); // Password should be decrypted when accessing $this->assertEquals($plainPassword, $account->password); // But encrypted in the database $this->assertNotEquals($plainPassword, $account->getAttributes()['password']); $this->assertNotNull($account->getAttributes()['password']); } public function test_password_with_specific_value(): void { $password = 'specific-test-password'; $account = PlatformAccount::factory()->create(['password' => $password]); $this->assertEquals($password, $account->password); $this->assertNotEquals($password, $account->getAttributes()['password']); } public function test_password_encryption_is_different_each_time(): void { $password = 'same-password'; $account1 = PlatformAccount::factory()->create(['password' => $password]); $account2 = PlatformAccount::factory()->create(['password' => $password]); $this->assertEquals($password, $account1->password); $this->assertEquals($password, $account2->password); $this->assertNotEquals($account1->getAttributes()['password'], $account2->getAttributes()['password']); } public function test_password_decryption_handles_corruption(): void { $account = PlatformAccount::factory()->create(); $originalPassword = $account->password; // Since the password attribute has special handling, this test verifies the basic functionality $this->assertNotNull($originalPassword); $this->assertIsString($originalPassword); } public function test_get_active_static_method(): void { // Create active and inactive accounts $activeAccount1 = PlatformAccount::factory()->create([ 'platform' => PlatformEnum::LEMMY, 'is_active' => true ]); $activeAccount2 = PlatformAccount::factory()->create([ 'platform' => PlatformEnum::LEMMY, 'is_active' => true ]); $inactiveAccount = PlatformAccount::factory()->create([ 'platform' => PlatformEnum::LEMMY, 'is_active' => false ]); $activeAccounts = PlatformAccount::getActive(PlatformEnum::LEMMY); $this->assertCount(2, $activeAccounts); $this->assertTrue($activeAccounts->contains('id', $activeAccount1->id)); $this->assertTrue($activeAccounts->contains('id', $activeAccount2->id)); $this->assertFalse($activeAccounts->contains('id', $inactiveAccount->id)); } public function test_set_as_active_method(): void { // Create multiple accounts for same platform $account1 = PlatformAccount::factory()->create([ 'platform' => PlatformEnum::LEMMY, 'is_active' => true ]); $account2 = PlatformAccount::factory()->create([ 'platform' => PlatformEnum::LEMMY, 'is_active' => true ]); $account3 = PlatformAccount::factory()->create([ 'platform' => PlatformEnum::LEMMY, 'is_active' => false ]); // Set account3 as active $account3->setAsActive(); // Refresh all accounts $account1->refresh(); $account2->refresh(); $account3->refresh(); // Only account3 should be active $this->assertFalse($account1->is_active); $this->assertFalse($account2->is_active); $this->assertTrue($account3->is_active); } public function test_belongs_to_many_channels_relationship(): void { $account = PlatformAccount::factory()->create(); $channel1 = PlatformChannel::factory()->create(); $channel2 = PlatformChannel::factory()->create(); // Attach channels with pivot data $account->channels()->attach($channel1->id, [ 'is_active' => true, 'priority' => 100 ]); $account->channels()->attach($channel2->id, [ 'is_active' => false, 'priority' => 50 ]); $channels = $account->channels; $this->assertCount(2, $channels); $this->assertTrue($channels->contains('id', $channel1->id)); $this->assertTrue($channels->contains('id', $channel2->id)); // Test pivot data $channel1FromRelation = $channels->find($channel1->id); $this->assertEquals(1, $channel1FromRelation->pivot->is_active); $this->assertEquals(100, $channel1FromRelation->pivot->priority); $channel2FromRelation = $channels->find($channel2->id); $this->assertEquals(0, $channel2FromRelation->pivot->is_active); $this->assertEquals(50, $channel2FromRelation->pivot->priority); } public function test_active_channels_relationship(): void { $account = PlatformAccount::factory()->create(); $activeChannel1 = PlatformChannel::factory()->create(); $activeChannel2 = PlatformChannel::factory()->create(); $inactiveChannel = PlatformChannel::factory()->create(); // Attach channels $account->channels()->attach($activeChannel1->id, [ 'is_active' => true, 'priority' => 100 ]); $account->channels()->attach($activeChannel2->id, [ 'is_active' => true, 'priority' => 200 ]); $account->channels()->attach($inactiveChannel->id, [ 'is_active' => false, 'priority' => 150 ]); $activeChannels = $account->activeChannels; $this->assertCount(2, $activeChannels); $this->assertTrue($activeChannels->contains('id', $activeChannel1->id)); $this->assertTrue($activeChannels->contains('id', $activeChannel2->id)); $this->assertFalse($activeChannels->contains('id', $inactiveChannel->id)); // Test ordering by priority descending $channelIds = $activeChannels->pluck('id')->toArray(); $this->assertEquals($activeChannel2->id, $channelIds[0]); // Priority 200 $this->assertEquals($activeChannel1->id, $channelIds[1]); // Priority 100 } public function test_account_creation_with_factory(): void { $account = PlatformAccount::factory()->create(); $this->assertInstanceOf(PlatformAccount::class, $account); $this->assertInstanceOf(PlatformEnum::class, $account->platform); $this->assertEquals(PlatformEnum::LEMMY, $account->platform); $this->assertIsString($account->instance_url); $this->assertIsString($account->username); $this->assertEquals('test-password', $account->password); $this->assertIsBool($account->is_active); $this->assertTrue($account->is_active); $this->assertEquals('untested', $account->status); $this->assertIsArray($account->settings); } public function test_account_creation_with_explicit_values(): void { $settings = ['custom' => 'value', 'nested' => ['key' => 'value']]; $timestamp = now()->subHours(1); $account = PlatformAccount::create([ 'platform' => PlatformEnum::LEMMY, 'instance_url' => 'https://lemmy.example.com', 'username' => 'testuser', 'password' => 'secret123', 'settings' => $settings, 'is_active' => false, 'last_tested_at' => $timestamp, 'status' => 'working' ]); $this->assertEquals(PlatformEnum::LEMMY, $account->platform); $this->assertEquals('https://lemmy.example.com', $account->instance_url); $this->assertEquals('testuser', $account->username); $this->assertEquals('secret123', $account->password); $this->assertEquals($settings, $account->settings); $this->assertFalse($account->is_active); $this->assertEquals($timestamp->format('Y-m-d H:i:s'), $account->last_tested_at->format('Y-m-d H:i:s')); $this->assertEquals('working', $account->status); } public function test_account_factory_states(): void { $inactiveAccount = PlatformAccount::factory()->inactive()->create(); $this->assertFalse($inactiveAccount->is_active); $testedAccount = PlatformAccount::factory()->tested()->create(); $this->assertNotNull($testedAccount->last_tested_at); $this->assertEquals('working', $testedAccount->status); $failedAccount = PlatformAccount::factory()->failed()->create(); $this->assertNotNull($failedAccount->last_tested_at); $this->assertEquals('failed', $failedAccount->status); } public function test_account_update(): void { $account = PlatformAccount::factory()->create([ 'username' => 'original_user', 'is_active' => true ]); $account->update([ 'username' => 'updated_user', 'is_active' => false ]); $account->refresh(); $this->assertEquals('updated_user', $account->username); $this->assertFalse($account->is_active); } public function test_account_deletion(): void { $account = PlatformAccount::factory()->create(); $accountId = $account->id; $account->delete(); $this->assertDatabaseMissing('platform_accounts', ['id' => $accountId]); } public function test_account_settings_can_be_empty_array(): void { $account = PlatformAccount::factory()->create(['settings' => []]); $this->assertIsArray($account->settings); $this->assertEmpty($account->settings); } public function test_account_settings_can_be_complex_structure(): void { $complexSettings = [ 'authentication' => [ 'method' => 'jwt', 'timeout' => 30 ], 'features' => ['posting', 'commenting'], 'rate_limits' => [ 'posts_per_hour' => 10, 'comments_per_hour' => 50 ] ]; $account = PlatformAccount::factory()->create(['settings' => $complexSettings]); $this->assertEquals($complexSettings, $account->settings); $this->assertEquals('jwt', $account->settings['authentication']['method']); $this->assertEquals(['posting', 'commenting'], $account->settings['features']); } public function test_account_can_have_null_last_tested_at(): void { $account = PlatformAccount::factory()->create(['last_tested_at' => null]); $this->assertNull($account->last_tested_at); } public function test_account_timestamps(): void { $account = PlatformAccount::factory()->create(); $this->assertNotNull($account->created_at); $this->assertNotNull($account->updated_at); $this->assertInstanceOf(\Carbon\Carbon::class, $account->created_at); $this->assertInstanceOf(\Carbon\Carbon::class, $account->updated_at); } public function test_account_can_have_multiple_channels_with_different_priorities(): void { $account = PlatformAccount::factory()->create(); $channel1 = PlatformChannel::factory()->create(); $channel2 = PlatformChannel::factory()->create(); $channel3 = PlatformChannel::factory()->create(); // Attach channels with different priorities $account->channels()->attach([ $channel1->id => ['is_active' => true, 'priority' => 300], $channel2->id => ['is_active' => true, 'priority' => 100], $channel3->id => ['is_active' => false, 'priority' => 200] ]); $allChannels = $account->channels; $activeChannels = $account->activeChannels; $this->assertCount(3, $allChannels); $this->assertCount(2, $activeChannels); // Test that we can access pivot data foreach ($allChannels as $channel) { $this->assertNotNull($channel->pivot->priority); $this->assertIsInt($channel->pivot->is_active); } } public function test_password_withoutObjectCaching_prevents_caching(): void { $account = PlatformAccount::factory()->create(['password' => 'original']); // Access password to potentially cache it $originalPassword = $account->password; $this->assertEquals('original', $originalPassword); // Update password directly in database $account->update(['password' => 'updated']); // Since withoutObjectCaching is used, the new value should be retrieved $account->refresh(); $this->assertEquals('updated', $account->password); } }