renderer = new TreeHtmlRenderer('admin'); $this->dateObj = new stdClass(); $this->dateObj->month = 1; $this->dateObj->year = 2024; $this->dateObj->start_date = '2024-01-01 00:00:00'; $this->dateObj->end_date = '2024-01-31 23:59:59'; } /** @test */ public function constructor_sets_init_from_correctly() { $adminRenderer = new TreeHtmlRenderer('admin'); $memberRenderer = new TreeHtmlRenderer('member'); $defaultRenderer = new TreeHtmlRenderer(); // Using reflection to access private property $reflection = new \ReflectionClass(TreeHtmlRenderer::class); $property = $reflection->getProperty('initFrom'); $property->setAccessible(true); $this->assertEquals('admin', $property->getValue($adminRenderer)); $this->assertEquals('member', $property->getValue($memberRenderer)); $this->assertEquals('member', $property->getValue($defaultRenderer)); } /** @test */ public function renderTree_returns_info_message_for_empty_array() { $result = $this->renderer->renderTree([]); $this->assertStringContainsString('Keine Business-User gefunden', $result); $this->assertStringContainsString('alert-info', $result); } /** @test */ public function renderTree_generates_html_structure_for_business_users() { // Create mock business user items $businessUsers = [ $this->createMockBusinessUser(1, 'John', 'Doe', 'john@example.com', true), $this->createMockBusinessUser(2, 'Jane', 'Smith', 'jane@example.com', false) ]; $result = $this->renderer->renderTree($businessUsers); // Check basic HTML structure $this->assertStringContainsString('
    ', $result); $this->assertStringContainsString('
', $result); $this->assertStringContainsString('dd-item', $result); // Check user data is included $this->assertStringContainsString('John Doe', $result); $this->assertStringContainsString('Jane Smith', $result); $this->assertStringContainsString('john@example.com', $result); $this->assertStringContainsString('jane@example.com', $result); } /** @test */ public function renderTree_includes_admin_buttons_for_admin_init() { $adminRenderer = new TreeHtmlRenderer('admin'); $businessUsers = [ $this->createMockBusinessUser(1, 'John', 'Doe', 'john@example.com', true) ]; $result = $adminRenderer->renderTree($businessUsers); // Should include calculator button for admin $this->assertStringContainsString('fa-calculator', $result); $this->assertStringContainsString('business-user-detail', $result); } /** @test */ public function renderTree_excludes_admin_buttons_for_member_init() { $memberRenderer = new TreeHtmlRenderer('member'); $businessUsers = [ $this->createMockBusinessUser(1, 'John', 'Doe', 'john@example.com', true) ]; $result = $memberRenderer->renderTree($businessUsers); // Should not include calculator button for regular members $this->assertStringNotContainsString('fa-calculator', $result); } /** @test */ public function renderTree_handles_inactive_accounts_correctly() { $businessUsers = [ $this->createMockBusinessUser(1, 'Active', 'User', 'active@example.com', true), $this->createMockBusinessUser(2, 'Inactive', 'User', 'inactive@example.com', false) ]; $result = $this->renderer->renderTree($businessUsers); // Active user should have primary color icon $this->assertStringContainsString('text-primary', $result); // Inactive user should have danger/muted styling $this->assertStringContainsString('text-danger', $result); $this->assertStringContainsString('text-muted', $result); } /** @test */ public function renderParentless_returns_empty_message_for_empty_array() { $result = $this->renderer->renderParentless([]); $this->assertStringContainsString('Keine parentlosen User gefunden', $result); $this->assertStringContainsString('alert-info', $result); } /** @test */ public function renderParentless_generates_list_for_parentless_users() { $parentlessUsers = [ $this->createMockBusinessUser(1, 'Orphan', 'User', 'orphan@example.com', true) ]; $result = $this->renderer->renderParentless($parentlessUsers); $this->assertStringContainsString('dd-item', $result); $this->assertStringContainsString('Orphan User', $result); $this->assertStringContainsString('orphan@example.com', $result); } /** @test */ public function renderSponsor_returns_no_sponsor_message_for_null() { $result = $this->renderer->renderSponsor(null); $this->assertStringContainsString('alert-warning', $result); $this->assertStringContainsString('team.no_sponsor_assigned', $result); } /** @test */ public function renderSponsor_generates_sponsor_html() { $sponsor = $this->createMockBusinessUser(1, 'Sponsor', 'User', 'sponsor@example.com', true); $result = $this->renderer->renderSponsor($sponsor); $this->assertStringContainsString('dd-item', $result); $this->assertStringContainsString('Sponsor User', $result); $this->assertStringContainsString('sponsor@example.com', $result); } /** @test */ public function renderSponsor_includes_admin_details_for_admin_init() { $adminRenderer = new TreeHtmlRenderer('admin'); $sponsor = $this->createMockBusinessUser(1, 'Sponsor', 'User', 'sponsor@example.com', true); // Set some business data $sponsor->sales_volume_points_KP_sum = 1000; $sponsor->sales_volume_total_sum = 5000; $result = $adminRenderer->renderSponsor($sponsor); $this->assertStringContainsString('1000', $result); $this->assertStringContainsString('5000', $result); $this->assertStringContainsString('total_points', $result); } /** @test */ public function renderItem_handles_deep_nesting() { // Create business user with nested children $parentUser = $this->createMockBusinessUser(1, 'Parent', 'User', 'parent@example.com', true); $childUser = $this->createMockBusinessUser(2, 'Child', 'User', 'child@example.com', true); // Set up nesting $parentUser->businessUserItems = [$childUser]; $result = $this->renderer->renderTree([$parentUser]); // Should contain both parent and child $this->assertStringContainsString('Parent User', $result); $this->assertStringContainsString('Child User', $result); // Should have nested structure $this->assertStringContainsString('
    ', $result); } /** @test */ public function html_output_is_properly_escaped() { $businessUsers = [ $this->createMockBusinessUser(1, 'John