mivita/tests/Unit/BusinessPlan/BusinessUserRepositoryTest.php
2025-08-12 18:01:59 +02:00

285 lines
No EOL
8.8 KiB
PHP

<?php
namespace Tests\Unit\BusinessPlan;
use Tests\TestCase;
use App\User;
use App\Models\UserAccount;
use App\Models\UserBusinessStructure;
use App\Services\BusinessPlan\BusinessUserRepository;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Cache;
class BusinessUserRepositoryTest extends TestCase
{
use RefreshDatabase;
private $repository;
protected function setUp(): void
{
parent::setUp();
$this->repository = new BusinessUserRepository(1, 2024);
}
/** @test */
public function constructor_initializes_dates_correctly()
{
$repository = new BusinessUserRepository(3, 2024);
// Using reflection to access private properties for testing
$reflection = new \ReflectionClass($repository);
$monthProperty = $reflection->getProperty('month');
$monthProperty->setAccessible(true);
$yearProperty = $reflection->getProperty('year');
$yearProperty->setAccessible(true);
$this->assertEquals(3, $monthProperty->getValue($repository));
$this->assertEquals(2024, $yearProperty->getValue($repository));
}
/** @test */
public function getStoredStructure_returns_completed_structure()
{
$structure = UserBusinessStructure::create([
'month' => 1,
'year' => 2024,
'structure' => json_encode([]),
'completed' => true
]);
$result = $this->repository->getStoredStructure();
$this->assertNotNull($result);
$this->assertEquals($structure->id, $result->id);
}
/** @test */
public function getStoredStructure_returns_null_for_incomplete_structure()
{
UserBusinessStructure::create([
'month' => 1,
'year' => 2024,
'structure' => json_encode([]),
'completed' => false
]);
$result = $this->repository->getStoredStructure();
$this->assertNull($result);
}
/** @test */
public function getRootUsers_returns_users_with_relations()
{
// Create root users (no sponsor)
$rootUser1 = User::factory()->create([
'm_sponsor' => null,
'm_level' => 1,
'payment_account' => '2024-01-15',
'active_date' => '2024-01-01'
]);
$rootUser2 = User::factory()->create([
'm_sponsor' => null,
'm_level' => 2,
'payment_account' => '2024-01-15',
'active_date' => '2024-01-01'
]);
// Create non-root user (has sponsor)
$childUser = User::factory()->create([
'm_sponsor' => $rootUser1->id,
'm_level' => 1,
'payment_account' => '2024-01-15',
'active_date' => '2024-01-01'
]);
// Create accounts
UserAccount::factory()->create(['user_id' => $rootUser1->id]);
UserAccount::factory()->create(['user_id' => $rootUser2->id]);
UserAccount::factory()->create(['user_id' => $childUser->id]);
$result = $this->repository->getRootUsers();
// Should return only root users (2), not child user
$this->assertEquals(2, $result->count());
// Verify relations are loaded
$firstUser = $result->first();
$this->assertTrue($firstUser->relationLoaded('account'));
}
/** @test */
public function getUserWithRelations_returns_user_with_loaded_relations()
{
$user = User::factory()->create([
'm_level' => 1,
'payment_account' => '2024-01-15'
]);
UserAccount::factory()->create(['user_id' => $user->id]);
$result = $this->repository->getUserWithRelations($user->id);
$this->assertNotNull($result);
$this->assertEquals($user->id, $result->id);
$this->assertTrue($result->relationLoaded('account'));
$this->assertTrue($result->relationLoaded('userLevel'));
}
/** @test */
public function getUserWithRelations_returns_null_for_non_existent_user()
{
$result = $this->repository->getUserWithRelations(999);
$this->assertNull($result);
}
/** @test */
public function getParentlessUsers_excludes_processed_user_ids()
{
// Create users
$user1 = User::factory()->create([
'm_level' => 1,
'payment_account' => '2024-01-15',
'active_date' => '2024-01-01'
]);
$user2 = User::factory()->create([
'm_level' => 1,
'payment_account' => '2024-01-15',
'active_date' => '2024-01-01'
]);
$user3 = User::factory()->create([
'm_level' => 1,
'payment_account' => '2024-01-15',
'active_date' => '2024-01-01'
]);
// Create accounts
UserAccount::factory()->create(['user_id' => $user1->id]);
UserAccount::factory()->create(['user_id' => $user2->id]);
UserAccount::factory()->create(['user_id' => $user3->id]);
// Exclude user1 and user2
$excludeIds = [$user1->id, $user2->id];
$result = $this->repository->getParentlessUsers($excludeIds);
// Should only return user3
$this->assertEquals(1, $result->count());
$this->assertEquals($user3->id, $result->first()->id);
}
/** @test */
public function getSponsorForUser_returns_sponsor_user()
{
// Create sponsor
$sponsor = User::factory()->create(['m_level' => 2]);
UserAccount::factory()->create(['user_id' => $sponsor->id]);
// Create user with sponsor
$user = User::factory()->create(['m_sponsor' => $sponsor->id]);
UserAccount::factory()->create(['user_id' => $user->id]);
$result = $this->repository->getSponsorForUser($user->id);
$this->assertNotNull($result);
$this->assertEquals($sponsor->id, $result->id);
}
/** @test */
public function getSponsorForUser_returns_null_for_user_without_sponsor()
{
$user = User::factory()->create(['m_sponsor' => null]);
$result = $this->repository->getSponsorForUser($user->id);
$this->assertNull($result);
}
/** @test */
public function caching_works_correctly_for_root_users()
{
// Clear cache first
Cache::flush();
// Create root user
$rootUser = User::factory()->create([
'm_sponsor' => null,
'm_level' => 1,
'payment_account' => '2024-01-15',
'active_date' => '2024-01-01'
]);
UserAccount::factory()->create(['user_id' => $rootUser->id]);
// First call should hit database and cache result
$result1 = $this->repository->getRootUsers();
$this->assertEquals(1, $result1->count());
// Verify cache was set
$cacheKey = "root_users_1_2024";
$this->assertTrue(Cache::has($cacheKey));
// Second call should use cache
$result2 = $this->repository->getRootUsers();
$this->assertEquals(1, $result2->count());
}
/** @test */
public function lazy_loading_yields_users_in_batches()
{
// Create multiple users
for ($i = 0; $i < 5; $i++) {
$user = User::factory()->create([
'm_level' => 1,
'payment_account' => '2024-01-15',
'active_date' => '2024-01-01'
]);
UserAccount::factory()->create(['user_id' => $user->id]);
}
$count = 0;
foreach ($this->repository->getParentlessUsers([]) as $user) {
$count++;
$this->assertInstanceOf(User::class, $user);
$this->assertTrue($user->relationLoaded('account'));
}
$this->assertEquals(5, $count);
}
/** @test */
public function memory_efficient_processing_works()
{
// Create many users to test memory efficiency
for ($i = 0; $i < 10; $i++) {
$user = User::factory()->create([
'm_level' => 1,
'payment_account' => '2024-01-15',
'active_date' => '2024-01-01'
]);
UserAccount::factory()->create(['user_id' => $user->id]);
}
$startMemory = memory_get_usage();
// Process users lazily
$count = 0;
foreach ($this->repository->getParentlessUsers([]) as $user) {
$count++;
// Simulate some processing
$user->toArray();
}
$endMemory = memory_get_usage();
$memoryUsed = $endMemory - $startMemory;
$this->assertEquals(10, $count);
// Memory usage should be reasonable (less than 10MB)
$this->assertLessThan(10 * 1024 * 1024, $memoryUsed);
}
}