user->create( array( 'role' => 'hvac_trainer' ) ); // Set a revenue target for the test user update_user_meta( self::$trainer_user_id, 'annual_revenue_target', 5000.00 ); // --- Create Test Events --- $now = time(); $one_day = DAY_IN_SECONDS; // Event 1: Past Event with tickets/revenue $event1_id = self::factory()->post->create( array( // Use self::factory() 'post_type' => Tribe__Events__Main::POSTTYPE, 'post_title' => 'Past Training Session', 'post_status' => 'publish', 'post_author' => self::$trainer_user_id, 'meta_input' => array( '_EventStartDate' => date( 'Y-m-d H:i:s', $now - ( 7 * $one_day ) ), '_EventEndDate' => date( 'Y-m-d H:i:s', $now - ( 7 * $one_day ) + HOUR_IN_SECONDS ), '_tribe_tickets_sold' => 10, '_tribe_revenue_total' => 250.00, '_EventOrganizerID' => self::$trainer_user_id, // Assuming trainer is organizer for simplicity ), ) ); update_post_meta( $event1_id, '_EventOrganizerID', self::$trainer_user_id ); // Explicitly set organizer meta self::$event_ids[] = $event1_id; // Event 2: Upcoming Event with tickets/revenue $event2_id = self::factory()->post->create( array( // Use self::factory() 'post_type' => Tribe__Events__Main::POSTTYPE, 'post_title' => 'Upcoming Workshop', 'post_status' => 'publish', 'post_author' => self::$trainer_user_id, 'meta_input' => array( '_EventStartDate' => date( 'Y-m-d H:i:s', $now + ( 7 * $one_day ) ), '_EventEndDate' => date( 'Y-m-d H:i:s', $now + ( 7 * $one_day ) + HOUR_IN_SECONDS ), '_tribe_tickets_sold' => 5, '_tribe_revenue_total' => 150.00, '_EventOrganizerID' => self::$trainer_user_id, ), ) ); update_post_meta( $event2_id, '_EventOrganizerID', self::$trainer_user_id ); // Explicitly set organizer meta self::$event_ids[] = $event2_id; // Event 3: Upcoming Draft Event (no tickets/revenue) $event3_id = self::factory()->post->create( array( // Use self::factory() 'post_type' => Tribe__Events__Main::POSTTYPE, 'post_title' => 'Draft Future Course', 'post_status' => 'draft', 'post_author' => self::$trainer_user_id, 'meta_input' => array( '_EventStartDate' => date( 'Y-m-d H:i:s', $now + ( 14 * $one_day ) ), '_EventEndDate' => date( 'Y-m-d H:i:s', $now + ( 14 * $one_day ) + HOUR_IN_SECONDS ), '_EventOrganizerID' => self::$trainer_user_id, ), ) ); update_post_meta( $event3_id, '_EventOrganizerID', self::$trainer_user_id ); // Explicitly set organizer meta self::$event_ids[] = $event3_id; // Event 4: Past Private Event (no tickets/revenue) $event4_id = self::factory()->post->create( array( // Use self::factory() 'post_type' => Tribe__Events__Main::POSTTYPE, 'post_title' => 'Past Private Meeting', 'post_status' => 'private', 'post_author' => self::$trainer_user_id, 'meta_input' => array( '_EventStartDate' => date( 'Y-m-d H:i:s', $now - ( 30 * $one_day ) ), '_EventEndDate' => date( 'Y-m-d H:i:s', $now - ( 30 * $one_day ) + HOUR_IN_SECONDS ), '_EventOrganizerID' => self::$trainer_user_id, ), ) ); update_post_meta( $event4_id, '_EventOrganizerID', self::$trainer_user_id ); // Explicitly set organizer meta self::$event_ids[] = $event4_id; // Event 5: Another Upcoming Event (publish) $event5_id = self::factory()->post->create( array( // Use self::factory() 'post_type' => Tribe__Events__Main::POSTTYPE, 'post_title' => 'Another Upcoming Event', 'post_status' => 'publish', 'post_author' => self::$trainer_user_id, 'meta_input' => array( '_EventStartDate' => date( 'Y-m-d H:i:s', $now + ( 3 * $one_day ) ), '_EventEndDate' => date( 'Y-m-d H:i:s', $now + ( 3 * $one_day ) + HOUR_IN_SECONDS ), '_tribe_tickets_sold' => 0, // No tickets sold yet '_tribe_revenue_total' => 0.00, '_EventOrganizerID' => self::$trainer_user_id, ), ) ); update_post_meta( $event5_id, '_EventOrganizerID', self::$trainer_user_id ); // Explicitly set organizer meta self::$event_ids[] = $event5_id; // Ensure the HVAC_Dashboard_Data class is loaded using the correct path // Assumes ABSPATH is defined correctly in the bootstrap process require_once ABSPATH . 'wp-content/plugins/hvac-community-events/includes/class-hvac-dashboard-data.php'; } /** * Clean up the test environment after the class runs. */ public static function tearDownAfterClass(): void { // Correct method name and add return type hint // Delete the test user wp_delete_user( self::$trainer_user_id ); // Delete the test events foreach ( self::$event_ids as $event_id ) { wp_delete_post( $event_id, true ); // Force delete } self::$event_ids = []; parent::tearDownAfterClass(); // Call parent's tearDownAfterClass } /** * Test the get_total_events_count method. */ public function test_get_total_events_count() { $dashboard_data = new HVAC_Dashboard_Data( self::$trainer_user_id ); $this->assertEquals( 5, $dashboard_data->get_total_events_count(), 'Total event count should be 5.' ); } /** * Test the get_upcoming_events_count method. */ public function test_get_upcoming_events_count() { $dashboard_data = new HVAC_Dashboard_Data( self::$trainer_user_id ); // Events 2, 3, 5 are upcoming (publish, draft, publish) - but method only counts publish/future $this->assertEquals( 2, $dashboard_data->get_upcoming_events_count(), 'Upcoming event count should be 2 (published/future only).' ); } /** * Test the get_past_events_count method. */ public function test_get_past_events_count() { $dashboard_data = new HVAC_Dashboard_Data( self::$trainer_user_id ); // Events 1, 4 are past (publish, private) $this->assertEquals( 2, $dashboard_data->get_past_events_count(), 'Past event count should be 2.' ); } /** * Test the get_total_tickets_sold method. */ public function test_get_total_tickets_sold() { $dashboard_data = new HVAC_Dashboard_Data( self::$trainer_user_id ); // Event 1 (10) + Event 2 (5) = 15 $this->assertEquals( 15, $dashboard_data->get_total_tickets_sold(), 'Total tickets sold should be 15.' ); } /** * Test the get_total_revenue method. */ public function test_get_total_revenue() { $dashboard_data = new HVAC_Dashboard_Data( self::$trainer_user_id ); // Event 1 (250.00) + Event 2 (150.00) = 400.00 $this->assertEqualsWithDelta( 400.00, $dashboard_data->get_total_revenue(), 0.01, 'Total revenue should be 400.00.' ); } /** * Test the get_annual_revenue_target method. */ public function test_get_annual_revenue_target() { $dashboard_data = new HVAC_Dashboard_Data( self::$trainer_user_id ); $this->assertEqualsWithDelta( 5000.00, $dashboard_data->get_annual_revenue_target(), 0.01, 'Annual revenue target should be 5000.00.' ); // Test case where target is not set $user_no_target_id = self::factory()->user->create( array( 'role' => 'hvac_trainer' ) ); // Already using self::factory() - No change needed here, but checking $dashboard_data_no_target = new HVAC_Dashboard_Data( $user_no_target_id ); $this->assertNull( $dashboard_data_no_target->get_annual_revenue_target(), 'Annual revenue target should be null when not set.' ); wp_delete_user( $user_no_target_id ); // Clean up temporary user } /** * Test the get_events_table_data method - default filter ('all'). */ public function test_get_events_table_data_all() { $dashboard_data = new HVAC_Dashboard_Data( self::$trainer_user_id ); $table_data = $dashboard_data->get_events_table_data( 'all' ); $this->assertIsArray( $table_data, 'Table data should be an array.' ); $this->assertCount( 5, $table_data, 'Table data should contain 5 events for "all" filter.' ); // Basic check on the structure of the first event (most recent - Event 3 Draft) $first_event = $table_data[0]; $this->assertArrayHasKey( 'id', $first_event ); $this->assertArrayHasKey( 'status', $first_event ); $this->assertArrayHasKey( 'name', $first_event ); $this->assertArrayHasKey( 'link', $first_event ); // Now WP permalink $this->assertArrayHasKey( 'start_date_ts', $first_event ); // Check for timestamp $this->assertArrayHasKey( 'organizer_id', $first_event ); // Check for organizer ID $this->assertArrayHasKey( 'capacity', $first_event ); $this->assertArrayHasKey( 'sold', $first_event ); $this->assertArrayHasKey( 'revenue', $first_event ); $this->assertEquals( 'Draft Future Course', $first_event['name'] ); $this->assertEquals( 'draft', $first_event['status'] ); } /** * Test the get_events_table_data method - 'publish' filter. */ public function test_get_events_table_data_publish() { $dashboard_data = new HVAC_Dashboard_Data( self::$trainer_user_id ); $table_data = $dashboard_data->get_events_table_data( 'publish' ); $this->assertIsArray( $table_data, 'Table data should be an array.' ); $this->assertCount( 3, $table_data, 'Table data should contain 3 events for "publish" filter.' ); // Events 1, 2, 5 // Check statuses foreach ( $table_data as $event ) { $this->assertEquals( 'publish', $event['status'] ); } } /** * Test the get_events_table_data method - 'draft' filter. */ public function test_get_events_table_data_draft() { $dashboard_data = new HVAC_Dashboard_Data( self::$trainer_user_id ); $table_data = $dashboard_data->get_events_table_data( 'draft' ); $this->assertIsArray( $table_data, 'Table data should be an array.' ); $this->assertCount( 1, $table_data, 'Table data should contain 1 event for "draft" filter.' ); // Event 3 $this->assertEquals( 'draft', $table_data[0]['status'] ); } /** * Test the get_events_table_data method - 'private' filter. */ public function test_get_events_table_data_private() { $dashboard_data = new HVAC_Dashboard_Data( self::$trainer_user_id ); $table_data = $dashboard_data->get_events_table_data( 'private' ); $this->assertIsArray( $table_data, 'Table data should be an array.' ); $this->assertCount( 1, $table_data, 'Table data should contain 1 event for "private" filter.' ); // Event 4 $this->assertEquals( 'private', $table_data[0]['status'] ); } // Add more tests if needed for edge cases, different data scenarios, etc. } // End class Test_HVAC_Dashboard_Data