Files
tonys-sportspress-enhancements/tests/test-sp-schedule-exporter.php
Anthony Correa 43033ddfb2 Add greyscale printable calendar mode
Add a black_white URL option for printable calendars and expose it in both printable URL builders.

Apply a high-legibility greyscale print style with white day cells, grey event blocks, and dark borders/text.

Condense month-cell event typography to fit more matchup text in each calendar day.

Cover black_white propagation in the printable URL helper test.
2026-05-18 18:35:08 -05:00

342 lines
11 KiB
PHP

<?php
/**
* Tests for schedule exporter and printable schedule helpers.
*
* @package Tonys_Sportspress_Enhancements
*/
/**
* Schedule exporter tests.
*/
class Test_SP_Schedule_Exporter extends WP_UnitTestCase {
/**
* Original request globals.
*
* @var array
*/
private $original_get = array();
/**
* Set up shared test fixtures.
*/
public function set_up() {
parent::set_up();
$this->original_get = $_GET;
foreach ( array( 'sp_venue', 'sp_league', 'sp_season' ) as $taxonomy ) {
if ( ! taxonomy_exists( $taxonomy ) ) {
register_taxonomy( $taxonomy, 'sp_event' );
}
}
}
/**
* Restore request globals.
*/
public function tear_down() {
$_GET = $this->original_get;
parent::tear_down();
}
/**
* Create a SportsPress team post.
*
* @param string $name Team name.
* @return int
*/
private function create_team( $name ) {
return self::factory()->post->create(
array(
'post_type' => 'sp_team',
'post_status' => 'publish',
'post_title' => $name,
)
);
}
/**
* Create a SportsPress event with ordered teams.
*
* @param int $home_id Home team ID.
* @param int $away_id Away team ID.
* @param int[] $venue_ids Venue IDs.
* @return int
*/
private function create_event( $home_id, $away_id, $venue_ids = array() ) {
$event_id = self::factory()->post->create(
array(
'post_type' => 'sp_event',
'post_status' => 'publish',
'post_title' => 'Game',
'post_date' => '2026-05-20 18:00:00',
'post_date_gmt' => '2026-05-20 23:00:00',
)
);
add_post_meta( $event_id, 'sp_team', (string) $home_id );
add_post_meta( $event_id, 'sp_team', (string) $away_id );
if ( ! empty( $venue_ids ) ) {
wp_set_object_terms( $event_id, $venue_ids, 'sp_venue' );
}
return $event_id;
}
/**
* Multiple selected team IDs should be retained in request order.
*/
public function test_resolve_team_ids_accepts_multiple_request_values() {
$team_one = $this->create_team( 'Blue' );
$team_two = $this->create_team( 'Red' );
$teams = array( get_post( $team_one ), get_post( $team_two ) );
$_GET['team_id'] = array( (string) $team_one, (string) $team_two );
$this->assertSame( array( $team_one, $team_two ), tse_sp_schedule_exporter_resolve_team_ids( $teams ) );
}
/**
* Printable URLs should carry multiple team IDs and the selected field.
*/
public function test_printable_url_accepts_multiple_teams_and_field() {
$url = tse_sp_schedule_exporter_get_printable_url( array( 12, 34 ), 56, 'letter', 78, false, 90, true );
$query = array();
wp_parse_str( (string) wp_parse_url( $url, PHP_URL_QUERY ), $query );
$this->assertSame( '12,34', $query['sp_team'] );
$this->assertSame( '90', $query['sp_field'] );
$this->assertSame( 'name', $query['team_label'] );
$this->assertSame( 'name', $query['field_label'] );
$this->assertSame( 'selected_first', $query['title_format'] );
$this->assertSame( '1', $query['month_pages'] );
}
/**
* Printable URLs should carry selected team and field label modes.
*/
public function test_printable_url_accepts_label_modes() {
$url = tse_sp_schedule_exporter_get_printable_url( 12, 56, 'letter', 78, false, 90, false, 'shortname', 'abbreviation' );
$query = array();
wp_parse_str( (string) wp_parse_url( $url, PHP_URL_QUERY ), $query );
$this->assertSame( 'shortname', $query['team_label'] );
$this->assertSame( 'abbreviation', $query['field_label'] );
}
/**
* Printable URLs should carry black-and-white mode when requested.
*/
public function test_printable_url_accepts_black_white_mode() {
$url = tse_sp_schedule_exporter_get_printable_url( 12, 56, 'letter', 78, false, 90, false, 'name', 'name', 'selected_first', true );
$query = array();
wp_parse_str( (string) wp_parse_url( $url, PHP_URL_QUERY ), $query );
$this->assertSame( '1', $query['black_white'] );
}
/**
* Single-team printable entries should keep the existing opponent perspective.
*/
public function test_printable_single_team_entries_keep_opponent_perspective() {
$home_id = $this->create_team( 'Home Team' );
$away_id = $this->create_team( 'Away Team' );
$venue_id = self::factory()->term->create( array( 'taxonomy' => 'sp_venue', 'name' => 'North Field' ) );
$this->create_event( $home_id, $away_id, array( $venue_id ) );
$printable = Tony_Sportspress_Printable_Calendars::instance();
$method = new ReflectionMethod( $printable, 'get_schedule_entries' );
$method->setAccessible( true );
$entries = $method->invoke( $printable, $home_id, 0, 0, array() );
$this->assertCount( 1, $entries );
$this->assertFalse( $entries[0]['is_matchup'] );
$this->assertTrue( $entries[0]['is_home'] );
$this->assertSame( 'Away Team', $entries[0]['opponent_name'] );
}
/**
* Printable entries should honor requested team and field labels.
*/
public function test_printable_entries_honor_label_modes() {
$home_id = $this->create_team( 'Home Team' );
$away_id = $this->create_team( 'Away Team' );
$venue_id = self::factory()->term->create( array( 'taxonomy' => 'sp_venue', 'name' => 'North Field' ) );
update_post_meta( $away_id, 'sp_abbreviation', 'AWY' );
update_term_meta( $venue_id, 'tse_abbreviation', 'NF' );
$this->create_event( $home_id, $away_id, array( $venue_id ) );
$printable = Tony_Sportspress_Printable_Calendars::instance();
$method = new ReflectionMethod( $printable, 'get_schedule_entries' );
$method->setAccessible( true );
$entries = $method->invoke( $printable, $home_id, 0, 0, array(), 'abbreviation', 'abbreviation' );
$this->assertCount( 1, $entries );
$this->assertSame( 'AWY', $entries[0]['opponent_name'] );
$this->assertSame( 'NF', $entries[0]['venue_label'] );
}
/**
* Team CSV layout should support multiple selected teams with away-first context.
*/
public function test_team_export_multiple_selected_teams_uses_away_team_first() {
$home_id = $this->create_team( 'Home Team' );
$away_id = $this->create_team( 'Away Team' );
$this->create_event( $home_id, $away_id );
$events = tse_sp_event_export_get_events(
array(
'team_ids' => array( $home_id, $away_id ),
)
);
$this->assertCount( 1, $events );
$this->assertSame( 'Away Team', $events[0]['team_name'] );
$this->assertSame( 'Away Team at Home Team', $events[0]['title'] );
$this->assertSame( 'at', $events[0]['separator'] );
$this->assertSame( 'Home Team', $events[0]['opponent_name'] );
$this->assertSame( 'Away', $events[0]['location_flag'] );
}
/**
* Team CSV layout should use vs when the selected team is home.
*/
public function test_team_export_home_selected_team_uses_vs_separator() {
$home_id = $this->create_team( 'Home Team' );
$away_id = $this->create_team( 'Away Team' );
$this->create_event( $home_id, $away_id );
$events = tse_sp_event_export_get_events(
array(
'team_ids' => array( $home_id ),
)
);
$this->assertCount( 1, $events );
$this->assertSame( 'Home Team', $events[0]['team_name'] );
$this->assertSame( 'Away Team', $events[0]['title'] );
$this->assertSame( 'vs', $events[0]['separator'] );
$this->assertSame( 'Away Team', $events[0]['opponent_name'] );
$this->assertSame( 'Home', $events[0]['location_flag'] );
}
/**
* Team CSV layout should use at when the selected team is away.
*/
public function test_team_export_away_selected_team_uses_at_separator() {
$home_id = $this->create_team( 'Home Team' );
$away_id = $this->create_team( 'Away Team' );
$this->create_event( $home_id, $away_id );
$events = tse_sp_event_export_get_events(
array(
'team_ids' => array( $away_id ),
)
);
$this->assertCount( 1, $events );
$this->assertSame( 'Away Team', $events[0]['team_name'] );
$this->assertSame( 'Home Team', $events[0]['title'] );
$this->assertSame( 'at', $events[0]['separator'] );
$this->assertSame( 'Home Team', $events[0]['opponent_name'] );
$this->assertSame( 'Away', $events[0]['location_flag'] );
}
/**
* Matchup title format should ignore selected-team perspective.
*/
public function test_team_export_matchup_title_format_uses_away_at_home() {
$home_id = $this->create_team( 'Home Team' );
$away_id = $this->create_team( 'Away Team' );
$this->create_event( $home_id, $away_id );
$events = tse_sp_event_export_get_events(
array(
'team_ids' => array( $home_id ),
'title_format' => 'matchup',
)
);
$this->assertCount( 1, $events );
$this->assertSame( 'Away Team at Home Team', $events[0]['title'] );
}
/**
* Multi-team printable entries should use selected-team-first titles by default.
*/
public function test_printable_multi_team_entries_use_selected_first_titles() {
$home_id = $this->create_team( 'Home Team' );
$away_id = $this->create_team( 'Away Team' );
$venue_id = self::factory()->term->create( array( 'taxonomy' => 'sp_venue', 'name' => 'North Field' ) );
$this->create_event( $home_id, $away_id, array( $venue_id ) );
$printable = Tony_Sportspress_Printable_Calendars::instance();
$method = new ReflectionMethod( $printable, 'get_schedule_entries' );
$method->setAccessible( true );
$entries = $method->invoke( $printable, array( $home_id, $away_id ), 0, 0, array() );
$this->assertCount( 1, $entries );
$this->assertFalse( $entries[0]['is_matchup'] );
$this->assertSame( 'Away Team', $entries[0]['title_team_name'] );
$this->assertSame( 'at', $entries[0]['title_separator'] );
$this->assertSame( 'Home Team', $entries[0]['title_opponent_name'] );
}
/**
* Exactly one selected field should suppress per-event venue labels.
*/
public function test_render_month_grid_can_suppress_event_venue_label() {
$printable = Tony_Sportspress_Printable_Calendars::instance();
$method = new ReflectionMethod( $printable, 'render_month_grid' );
$method->setAccessible( true );
$entries = array(
'2026-05-20' => array(
array(
'day_key' => '2026-05-20',
'month_key' => '2026-05',
'timestamp' => strtotime( '2026-05-20 18:00:00' ),
'is_matchup' => true,
'away_team_name' => 'Away',
'home_team_name' => 'Home',
'event_time' => '6:00 PM',
'venue_label' => 'North',
'venue_name' => 'North Field',
'venue_key' => 'v:1',
),
),
);
ob_start();
$method->invoke(
$printable,
'2026-05',
$entries,
array( 'v:1' => array( 'name' => 'North Field', 'color' => '#1D4ED8' ) ),
array(
'primary' => '#1D4ED8',
'secondary' => '#DC2626',
'accent' => '#1D4ED8',
'ink' => '#111827',
'muted_ink' => '#334155',
),
true,
true
);
$output = ob_get_clean();
$this->assertStringContainsString( 'Away', $output );
$this->assertStringContainsString( 'Home', $output );
$this->assertStringNotContainsString( 'class="event-venue"', $output );
}
}