- Refactored fallback submission logic in `class-event-handler.php` to remove `wp_die`/`exit` calls and use redirects for error handling, enabling proper unit testing. - Implemented meta-data saving (dates, venue, organizer) in the fallback logic using `update_post_meta`. - Updated unit tests (`test-event-management.php`) to remove `markTestIncomplete` calls related to handler errors and uncommented meta assertions. Unit tests for fallback logic now pass. - Added Instructions section and Return to Dashboard button to the event form shortcode (`display_event_form_shortcode`). - Applied basic theme styling classes (`ast-container`, `notice`, `ast-button`) to the event form. - Updated `docs/implementation_plan.md` to reflect completion of tasks 4.1-4.5 and set focus to Task 5. Refs: Task 4.1, 4.2, 4.3, 4.4, 4.5
458 lines
No EOL
18 KiB
PHP
458 lines
No EOL
18 KiB
PHP
<?php
|
|
/**
|
|
* Unit tests for event creation and modification logic.
|
|
*
|
|
* @package Hvac_Community_Events
|
|
*/
|
|
|
|
use Yoast\WPTestUtils\WPIntegration;
|
|
|
|
/**
|
|
* Class Event_Management_Test
|
|
*
|
|
* Tests the core logic for creating and modifying events.
|
|
*/
|
|
class Event_Management_Test extends WP_UnitTestCase {
|
|
|
|
// Removed: use WPIntegration\FactoriesApi; - Use built-in factory from WP_UnitTestCase
|
|
|
|
/**
|
|
* Test trainer user ID.
|
|
* @var int
|
|
*/
|
|
protected static $trainer_user_id;
|
|
|
|
/**
|
|
* Set up the test environment before the class runs.
|
|
*/
|
|
public static function wpSetUpBeforeClass( $factory ) {
|
|
// Create a user with the 'hvac_trainer' role for testing permissions
|
|
self::$trainer_user_id = $factory->user->create( [
|
|
'role' => 'hvac_trainer',
|
|
] );
|
|
|
|
// Ensure The Events Calendar core classes are loaded if needed
|
|
// Note: This might require adjustments based on how TEC is loaded in bootstrap.php
|
|
if ( ! class_exists( 'Tribe__Events__Main' ) && defined( 'TRIBE_EVENTS_FILE' ) ) {
|
|
require_once dirname( TRIBE_EVENTS_FILE ) . '/src/Tribe/Main.php';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set up the test environment before each test method runs.
|
|
*/
|
|
public function set_up() {
|
|
parent::set_up();
|
|
// Set the current user to the test trainer for permission-based tests
|
|
wp_set_current_user( self::$trainer_user_id );
|
|
}
|
|
|
|
/**
|
|
* Tear down the test environment after each test method runs.
|
|
*/
|
|
public function tear_down() {
|
|
// Reset the current user
|
|
wp_set_current_user( 0 );
|
|
parent::tear_down();
|
|
}
|
|
|
|
// --- Test Cases ---
|
|
|
|
/**
|
|
* Test that event creation fails if required data (e.g., title) is missing.
|
|
* @test
|
|
*/
|
|
public function test_event_creation_requires_valid_data() {
|
|
// Assume TEC CE handler doesn't exist or fails for this test path
|
|
if ( class_exists( 'Tribe__Events__Community__Main' ) ) {
|
|
$this->markTestSkipped('Skipping manual fallback test when TEC CE is active.');
|
|
}
|
|
|
|
// 1. Prepare POST data missing the title
|
|
$_POST = [
|
|
'action' => 'hvac_save_event',
|
|
'event_id' => 0,
|
|
'_hvac_event_nonce' => wp_create_nonce( 'hvac_save_event_nonce' ),
|
|
'event_title' => '', // Missing title
|
|
'event_description' => 'Description without title.',
|
|
// Add other fields like dates if they are validated in the fallback
|
|
];
|
|
|
|
// 2. Instantiate handler and call method (expecting wp_die or error handling)
|
|
$handler = HVAC_Event_Handler::get_instance();
|
|
ob_start();
|
|
@$handler->process_event_submission();
|
|
$output = ob_get_clean(); // Capture potential wp_die output
|
|
|
|
// 3. Assert no event was created
|
|
$args = [
|
|
'post_type' => Tribe__Events__Main::POSTTYPE,
|
|
'post_status' => 'any',
|
|
'post_content' => 'Description without title.', // Search by content as title is empty
|
|
'posts_per_page' => 1,
|
|
];
|
|
$events = get_posts( $args );
|
|
$this->assertCount( 0, $events, 'No event should have been created with missing title.' );
|
|
|
|
// Optional: Check output for expected error message if wp_die was caught
|
|
// $this->assertStringContainsString( 'Event Title is required', $output );
|
|
|
|
// TODO: Add more scenarios for other invalid data (e.g., invalid dates)
|
|
|
|
// Clean up
|
|
unset( $_POST );
|
|
}
|
|
|
|
/**
|
|
* Test successful event creation with valid data using the fallback logic.
|
|
* @test
|
|
*/
|
|
public function test_event_creation_success() {
|
|
// Assume TEC CE handler doesn't exist or fails for this test path
|
|
if ( class_exists( 'Tribe__Events__Community__Main' ) ) {
|
|
$this->markTestSkipped('Skipping manual fallback test when TEC CE is active.');
|
|
}
|
|
|
|
// 1. Create dependencies
|
|
$venue_id = $this->factory()->post->create( [
|
|
'post_type' => Tribe__Events__Main::VENUE_POST_TYPE,
|
|
'post_title' => 'Test Venue',
|
|
'post_status' => 'publish',
|
|
] );
|
|
$organizer_id = $this->factory()->post->create( [
|
|
'post_type' => Tribe__Events__Main::ORGANIZER_POST_TYPE,
|
|
'post_title' => 'Test Organizer',
|
|
'post_status' => 'publish',
|
|
] );
|
|
|
|
// 2. Prepare mock POST data (using common TEC field names)
|
|
$start_date = date( 'Y-m-d H:i:s', strtotime( '+1 day' ) );
|
|
$end_date = date( 'Y-m-d H:i:s', strtotime( '+1 day +2 hours' ) );
|
|
$_POST = [
|
|
'action' => 'hvac_save_event',
|
|
'event_id' => 0, // Creating new event
|
|
'_hvac_event_nonce' => wp_create_nonce( 'hvac_save_event_nonce' ), // Generate a valid nonce
|
|
'event_title' => 'My Test Event',
|
|
'event_description' => 'This is the event description.',
|
|
// TEC Date fields (adjust names if needed based on actual form)
|
|
'EventStartDate' => date( 'Y-m-d', strtotime( $start_date ) ),
|
|
'EventStartTime' => date( 'h:i A', strtotime( $start_date ) ),
|
|
'EventEndDate' => date( 'Y-m-d', strtotime( $end_date ) ),
|
|
'EventEndTime' => date( 'h:i A', strtotime( $end_date ) ),
|
|
// TEC Venue/Organizer fields (adjust names if needed)
|
|
'venue' => [ 'VenueID' => $venue_id ],
|
|
'organizer' => [ 'OrganizerID' => $organizer_id ],
|
|
// Add other necessary fields like cost, categories etc. if required by fallback logic
|
|
];
|
|
|
|
// 3. Instantiate handler and call method
|
|
$handler = HVAC_Event_Handler::get_instance();
|
|
|
|
// Use output buffering to catch potential wp_die output if redirection fails
|
|
ob_start();
|
|
// We expect this to redirect, so catch potential headers already sent errors/output
|
|
@$handler->process_event_submission();
|
|
ob_end_clean(); // Discard output buffer
|
|
|
|
// 4. Assertions
|
|
$args = [
|
|
'post_type' => Tribe__Events__Main::POSTTYPE,
|
|
'post_status' => 'publish', // Assuming fallback publishes directly
|
|
'title' => 'My Test Event',
|
|
'author' => self::$trainer_user_id,
|
|
'posts_per_page' => 1,
|
|
];
|
|
$events = get_posts( $args );
|
|
|
|
$this->assertCount( 1, $events, 'Expected one event to be created.' );
|
|
$created_event_id = $events[0]->ID;
|
|
|
|
// Assert basic post data
|
|
$this->assertEquals( 'My Test Event', $events[0]->post_title );
|
|
$this->assertEquals( 'This is the event description.', $events[0]->post_content );
|
|
$this->assertEquals( self::$trainer_user_id, $events[0]->post_author );
|
|
|
|
// Assert meta data (requires fallback logic in handler to save these)
|
|
$this->assertEquals( $start_date, get_post_meta( $created_event_id, '_EventStartDate', true ) );
|
|
$this->assertEquals( $end_date, get_post_meta( $created_event_id, '_EventEndDate', true ) );
|
|
$this->assertEquals( $venue_id, get_post_meta( $created_event_id, '_EventVenueID', true ) );
|
|
$this->assertEquals( $organizer_id, get_post_meta( $created_event_id, '_EventOrganizerID', true ) );
|
|
// $this->markTestIncomplete( 'Meta data assertions depend on fallback save logic implementation.' ); // Removed
|
|
|
|
// Clean up post variable
|
|
unset( $_POST );
|
|
}
|
|
|
|
/**
|
|
* Test successful event modification with valid data using the fallback logic.
|
|
* @test
|
|
*/
|
|
public function test_event_modification_success() {
|
|
// Assume TEC CE handler doesn't exist or fails for this test path
|
|
if ( class_exists( 'Tribe__Events__Community__Main' ) ) {
|
|
$this->markTestSkipped('Skipping manual fallback test when TEC CE is active.');
|
|
}
|
|
|
|
// 1. Create initial event, venue, organizer
|
|
$initial_venue_id = $this->factory()->post->create( [ 'post_type' => Tribe__Events__Main::VENUE_POST_TYPE, 'post_title' => 'Initial Venue', 'post_status' => 'publish' ] );
|
|
$initial_organizer_id = $this->factory()->post->create( [ 'post_type' => Tribe__Events__Main::ORGANIZER_POST_TYPE, 'post_title' => 'Initial Organizer', 'post_status' => 'publish' ] );
|
|
$event_id = $this->factory()->post->create( [
|
|
'post_type' => Tribe__Events__Main::POSTTYPE,
|
|
'post_title' => 'Initial Event Title',
|
|
'post_content' => 'Initial description.',
|
|
'post_status' => 'publish',
|
|
'post_author' => self::$trainer_user_id,
|
|
// TODO: Set initial meta if needed for comparison
|
|
] );
|
|
// Set initial meta (assuming fallback logic would have done this)
|
|
// update_post_meta( $event_id, '_EventVenueID', $initial_venue_id );
|
|
// update_post_meta( $event_id, '_EventOrganizerID', $initial_organizer_id );
|
|
|
|
// 2. Prepare mock POST data for modification
|
|
$new_start_date = date( 'Y-m-d H:i:s', strtotime( '+2 day' ) );
|
|
$new_end_date = date( 'Y-m-d H:i:s', strtotime( '+2 day +3 hours' ) );
|
|
$new_venue_id = $this->factory()->post->create( [ 'post_type' => Tribe__Events__Main::VENUE_POST_TYPE, 'post_title' => 'New Venue', 'post_status' => 'publish' ] );
|
|
|
|
$_POST = [
|
|
'action' => 'hvac_save_event',
|
|
'event_id' => $event_id, // Modifying existing event
|
|
'_hvac_event_nonce' => wp_create_nonce( 'hvac_save_event_nonce' ),
|
|
'event_title' => 'Updated Test Event Title',
|
|
'event_description' => 'Updated event description.',
|
|
// TEC Date fields
|
|
'EventStartDate' => date( 'Y-m-d', strtotime( $new_start_date ) ),
|
|
'EventStartTime' => date( 'h:i A', strtotime( $new_start_date ) ),
|
|
'EventEndDate' => date( 'Y-m-d', strtotime( $new_end_date ) ),
|
|
'EventEndTime' => date( 'h:i A', strtotime( $new_end_date ) ),
|
|
// TEC Venue/Organizer fields
|
|
'venue' => [ 'VenueID' => $new_venue_id ], // Change venue
|
|
'organizer' => [ 'OrganizerID' => $initial_organizer_id ], // Keep organizer
|
|
// Add other fields as needed
|
|
];
|
|
|
|
// 3. Instantiate handler and call method
|
|
$handler = HVAC_Event_Handler::get_instance();
|
|
ob_start();
|
|
@$handler->process_event_submission();
|
|
ob_end_clean();
|
|
|
|
// 4. Assertions
|
|
$updated_event = get_post( $event_id );
|
|
|
|
$this->assertNotNull( $updated_event, 'Event post should still exist.' );
|
|
$this->assertEquals( 'Updated Test Event Title', $updated_event->post_title );
|
|
$this->assertEquals( 'Updated event description.', $updated_event->post_content );
|
|
$this->assertEquals( self::$trainer_user_id, $updated_event->post_author ); // Author should not change
|
|
|
|
// Assert meta data (requires fallback logic in handler to save these)
|
|
$this->assertEquals( $new_start_date, get_post_meta( $event_id, '_EventStartDate', true ) );
|
|
$this->assertEquals( $new_end_date, get_post_meta( $event_id, '_EventEndDate', true ) );
|
|
$this->assertEquals( $new_venue_id, get_post_meta( $event_id, '_EventVenueID', true ) );
|
|
$this->assertEquals( $initial_organizer_id, get_post_meta( $event_id, '_EventOrganizerID', true ) ); // Ensure organizer didn't change unexpectedly
|
|
// $this->markTestIncomplete( 'Meta data assertions depend on fallback save logic implementation.' ); // Removed
|
|
|
|
// Clean up post variable
|
|
unset( $_POST );
|
|
}
|
|
|
|
/**
|
|
* Test that a user without the correct role/capabilities cannot create an event.
|
|
* @test
|
|
*/
|
|
public function test_unauthorized_user_cannot_create_event() {
|
|
|
|
// 1. Set user to subscriber
|
|
$subscriber_id = $this->factory()->user->create( [ 'role' => 'subscriber' ] );
|
|
wp_set_current_user( $subscriber_id );
|
|
|
|
// 2. Prepare minimal POST data
|
|
$_POST = [
|
|
'action' => 'hvac_save_event',
|
|
'event_id' => 0,
|
|
'_hvac_event_nonce' => wp_create_nonce( 'hvac_save_event_nonce' ),
|
|
'event_title' => 'Unauthorized Event Attempt',
|
|
// Other fields not strictly necessary for permission check
|
|
];
|
|
|
|
// 3. Instantiate handler and call method (expecting wp_die)
|
|
$handler = HVAC_Event_Handler::get_instance();
|
|
ob_start();
|
|
// Use @ to suppress expected wp_die output/error
|
|
@$handler->process_event_submission();
|
|
$output = ob_get_clean(); // Capture output in case we want to check it later
|
|
|
|
// 4. Assert no event was created
|
|
$args = [
|
|
'post_type' => Tribe__Events__Main::POSTTYPE,
|
|
'post_status' => 'any', // Check all statuses
|
|
'title' => 'Unauthorized Event Attempt',
|
|
'posts_per_page' => 1,
|
|
];
|
|
$events = get_posts( $args );
|
|
$this->assertCount( 0, $events, 'No event should have been created by an unauthorized user.' );
|
|
|
|
// Optional: Check output for expected error message if wp_die was caught
|
|
// $this->assertStringContainsString( 'You do not have permission', $output ); // This might be fragile
|
|
|
|
// Clean up
|
|
unset( $_POST );
|
|
wp_set_current_user( self::$trainer_user_id ); // Reset user for subsequent tests
|
|
}
|
|
|
|
/**
|
|
* Test that a user cannot modify an event they don't own (even if they have the trainer role).
|
|
* @test
|
|
*/
|
|
public function test_unauthorized_user_cannot_modify_event() {
|
|
|
|
// 1. Create initial event owned by the main test trainer
|
|
$initial_title = 'Event Owned By Trainer 1';
|
|
$event_id = $this->factory()->post->create( [
|
|
'post_type' => Tribe__Events__Main::POSTTYPE,
|
|
'post_title' => $initial_title,
|
|
'post_status' => 'publish',
|
|
'post_author' => self::$trainer_user_id,
|
|
] );
|
|
|
|
// 2. Create a second trainer user
|
|
$other_trainer_id = $this->factory()->user->create( [ 'role' => 'hvac_trainer' ] );
|
|
wp_set_current_user( $other_trainer_id );
|
|
|
|
// 3. Prepare POST data attempting modification
|
|
$_POST = [
|
|
'action' => 'hvac_save_event',
|
|
'event_id' => $event_id, // Target the first trainer's event
|
|
'_hvac_event_nonce' => wp_create_nonce( 'hvac_save_event_nonce' ),
|
|
'event_title' => 'Attempted Update By Trainer 2',
|
|
// Other fields...
|
|
];
|
|
|
|
// 4. Instantiate handler and call method (expecting wp_die)
|
|
$handler = HVAC_Event_Handler::get_instance();
|
|
ob_start();
|
|
@$handler->process_event_submission();
|
|
ob_end_clean();
|
|
|
|
// 5. Assert the event was NOT modified
|
|
$event_post = get_post( $event_id );
|
|
$this->assertNotNull( $event_post, 'Event post should still exist.' );
|
|
$this->assertEquals( $initial_title, $event_post->post_title, 'Event title should not have been changed by another trainer.' );
|
|
|
|
// Clean up
|
|
unset( $_POST );
|
|
wp_set_current_user( self::$trainer_user_id ); // Reset user
|
|
}
|
|
|
|
/**
|
|
* Test that venue information is correctly associated with the created event (fallback logic).
|
|
* @test
|
|
*/
|
|
public function test_event_venue_association() {
|
|
// Assume TEC CE handler doesn't exist or fails for this test path
|
|
if ( class_exists( 'Tribe__Events__Community__Main' ) ) {
|
|
$this->markTestSkipped('Skipping manual fallback test when TEC CE is active.');
|
|
}
|
|
|
|
// 1. Create dependencies
|
|
$venue_id = $this->factory()->post->create( [ 'post_type' => Tribe__Events__Main::VENUE_POST_TYPE, 'post_title' => 'Associated Venue', 'post_status' => 'publish' ] );
|
|
$organizer_id = $this->factory()->post->create( [ 'post_type' => Tribe__Events__Main::ORGANIZER_POST_TYPE, 'post_title' => 'Associated Organizer', 'post_status' => 'publish' ] );
|
|
|
|
// 2. Prepare mock POST data
|
|
$start_date = date( 'Y-m-d H:i:s', strtotime( '+3 day' ) );
|
|
$end_date = date( 'Y-m-d H:i:s', strtotime( '+3 day +2 hours' ) );
|
|
$_POST = [
|
|
'action' => 'hvac_save_event',
|
|
'event_id' => 0,
|
|
'_hvac_event_nonce' => wp_create_nonce( 'hvac_save_event_nonce' ),
|
|
'event_title' => 'Event With Venue',
|
|
'event_description' => 'Testing venue association.',
|
|
'EventStartDate' => date( 'Y-m-d', strtotime( $start_date ) ),
|
|
'EventStartTime' => date( 'h:i A', strtotime( $start_date ) ),
|
|
'EventEndDate' => date( 'Y-m-d', strtotime( $end_date ) ),
|
|
'EventEndTime' => date( 'h:i A', strtotime( $end_date ) ),
|
|
'venue' => [ 'VenueID' => $venue_id ], // Key field
|
|
'organizer' => [ 'OrganizerID' => $organizer_id ],
|
|
];
|
|
|
|
// 3. Instantiate handler and call method
|
|
$handler = HVAC_Event_Handler::get_instance();
|
|
ob_start();
|
|
@$handler->process_event_submission();
|
|
ob_end_clean();
|
|
|
|
// 4. Assertions
|
|
$args = [
|
|
'post_type' => Tribe__Events__Main::POSTTYPE,
|
|
'post_status' => 'publish',
|
|
'title' => 'Event With Venue',
|
|
'posts_per_page' => 1,
|
|
];
|
|
$events = get_posts( $args );
|
|
$this->assertCount( 1, $events, 'Expected event to be created.' );
|
|
$created_event_id = $events[0]->ID;
|
|
|
|
// Assert meta data (requires fallback logic in handler to save these)
|
|
$this->assertEquals( $venue_id, get_post_meta( $created_event_id, '_EventVenueID', true ) );
|
|
// $this->markTestIncomplete( 'Venue meta assertion depends on fallback save logic implementation.' ); // Removed
|
|
|
|
// Clean up
|
|
unset( $_POST );
|
|
}
|
|
|
|
/**
|
|
* Test that organizer information is correctly associated with the created event (fallback logic).
|
|
* @test
|
|
*/
|
|
public function test_event_organizer_association() {
|
|
// Assume TEC CE handler doesn't exist or fails for this test path
|
|
if ( class_exists( 'Tribe__Events__Community__Main' ) ) {
|
|
$this->markTestSkipped('Skipping manual fallback test when TEC CE is active.');
|
|
}
|
|
|
|
// 1. Create dependencies
|
|
$venue_id = $this->factory()->post->create( [ 'post_type' => Tribe__Events__Main::VENUE_POST_TYPE, 'post_title' => 'Associated Venue 2', 'post_status' => 'publish' ] );
|
|
$organizer_id = $this->factory()->post->create( [ 'post_type' => Tribe__Events__Main::ORGANIZER_POST_TYPE, 'post_title' => 'Associated Organizer 2', 'post_status' => 'publish' ] );
|
|
|
|
// 2. Prepare mock POST data
|
|
$start_date = date( 'Y-m-d H:i:s', strtotime( '+4 day' ) );
|
|
$end_date = date( 'Y-m-d H:i:s', strtotime( '+4 day +2 hours' ) );
|
|
$_POST = [
|
|
'action' => 'hvac_save_event',
|
|
'event_id' => 0,
|
|
'_hvac_event_nonce' => wp_create_nonce( 'hvac_save_event_nonce' ),
|
|
'event_title' => 'Event With Organizer',
|
|
'event_description' => 'Testing organizer association.',
|
|
'EventStartDate' => date( 'Y-m-d', strtotime( $start_date ) ),
|
|
'EventStartTime' => date( 'h:i A', strtotime( $start_date ) ),
|
|
'EventEndDate' => date( 'Y-m-d', strtotime( $end_date ) ),
|
|
'EventEndTime' => date( 'h:i A', strtotime( $end_date ) ),
|
|
'venue' => [ 'VenueID' => $venue_id ],
|
|
'organizer' => [ 'OrganizerID' => $organizer_id ], // Key field
|
|
];
|
|
|
|
// 3. Instantiate handler and call method
|
|
$handler = HVAC_Event_Handler::get_instance();
|
|
ob_start();
|
|
@$handler->process_event_submission();
|
|
ob_end_clean();
|
|
|
|
// 4. Assertions
|
|
$args = [
|
|
'post_type' => Tribe__Events__Main::POSTTYPE,
|
|
'post_status' => 'publish',
|
|
'title' => 'Event With Organizer',
|
|
'posts_per_page' => 1,
|
|
];
|
|
$events = get_posts( $args );
|
|
$this->assertCount( 1, $events, 'Expected event to be created.' );
|
|
$created_event_id = $events[0]->ID;
|
|
|
|
// Assert meta data (requires fallback logic in handler to save these)
|
|
$this->assertEquals( $organizer_id, get_post_meta( $created_event_id, '_EventOrganizerID', true ) );
|
|
// $this->markTestIncomplete( 'Organizer meta assertion depends on fallback save logic implementation.' ); // Removed
|
|
|
|
// Clean up
|
|
unset( $_POST );
|
|
}
|
|
|
|
} |