Files
hoponhopofftickets/viator-collector/tests/test-structure.php
Amir Bagheri 930b7e0534 fix: paginated region/city pages, no routes before first save, safer structure save
- Add /{slug}/page/N/ rules and keep the page number through 301s
- Route only regions synced to a term, so unsaved presets never claim /europe/ etc.
- Flush rewrites on the request after activation so structure routes survive
- Suggest the existing term slug for new cities (keeps live /tour-destination/ URLs)
- Refuse saves without the editor sentinel; confirm before saving an empty structure
- Show term-sync failures to the admin instead of reporting success

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 15:33:01 +03:30

174 lines
6.5 KiB
PHP

<?php
/**
* VC_Structure unit tests.
*/
function vc_fixture_structure() {
return array(
array(
'name' => 'Europe',
'slug' => 'europe',
'term_id' => 0,
'cities' => array(
array( 'id' => '737', 'name' => 'Amsterdam', 'slug' => 'amsterdam' ),
array( 'id' => '479', 'name' => 'Paris', 'slug' => 'paris' ),
),
),
array(
'name' => 'Americas',
'slug' => 'americas',
'term_id' => 0,
'cities' => array(
array( 'id' => '678', 'name' => 'Boston', 'slug' => 'boston' ),
),
),
);
}
function vc_fixture_map() {
return array( '737' => 'Amsterdam', '479' => 'Paris', '678' => 'Boston', '22' => 'Victoria' );
}
function test_default_regions() {
$regions = VC_Structure::default_regions();
vc_assert_same(
array( 'uk', 'europe', 'asia', 'middle-east-and-africa', 'americas', 'australasia' ),
array_column( $regions, 'slug' )
);
vc_assert_same( 'Middle East and Africa', $regions[3]['name'] );
vc_assert_same( array(), $regions[0]['cities'] );
vc_assert_same( 0, $regions[0]['term_id'] );
}
function test_normalize_fills_slugs() {
$s = VC_Structure::normalize(
array(
array(
'name' => ' Middle East and Africa ',
'slug' => '',
'term_id' => '7',
'cities' => array(
array( 'id' => '', 'name' => 'Ghost', 'slug' => 'ghost' ),
array( 'id' => '828', 'name' => 'Dubai', 'slug' => '' ),
),
),
)
);
vc_assert_same( 'Middle East and Africa', $s[0]['name'] );
vc_assert_same( 'middle-east-and-africa', $s[0]['slug'] );
vc_assert_same( 7, $s[0]['term_id'] );
vc_assert_same( array( array( 'id' => '828', 'name' => 'Dubai', 'slug' => 'dubai' ) ), $s[0]['cities'] );
}
function test_validate_ok() {
vc_assert_same( array(), VC_Structure::validate( vc_fixture_structure(), vc_fixture_map(), array() ) );
}
function test_validate_unknown_city() {
$s = vc_fixture_structure();
$s[1]['cities'][0]['id'] = '999';
vc_assert_contains( 'City ID 999 is not a Viator destination.', VC_Structure::validate( $s, vc_fixture_map(), array() ) );
}
function test_validate_duplicate_city() {
$s = vc_fixture_structure();
$s[1]['cities'][] = array( 'id' => '737', 'name' => 'Amsterdam', 'slug' => 'amsterdam-2' );
vc_assert_contains( 'Amsterdam is listed more than once.', VC_Structure::validate( $s, vc_fixture_map(), array() ) );
}
function test_validate_duplicate_slug() {
$s = vc_fixture_structure();
$s[1]['slug'] = 'paris';
vc_assert_contains( 'Slug "paris" is used more than once.', VC_Structure::validate( $s, vc_fixture_map(), array() ) );
}
function test_validate_bad_slug() {
$s = vc_fixture_structure();
$s[0]['cities'][0]['slug'] = 'amsterdam!';
$s[1]['cities'][0]['slug'] = 'New York';
$errors = VC_Structure::validate( $s, vc_fixture_map(), array() );
vc_assert_contains( 'Slug "amsterdam!" is invalid: use only a-z, 0-9 and -.', $errors );
vc_assert_contains( 'Slug "New York" is invalid: use only a-z, 0-9 and -.', $errors );
}
function test_validate_reserved() {
$s = vc_fixture_structure();
$s[0]['cities'][0]['slug'] = 'contact';
vc_assert_contains( 'Slug "contact" is reserved.', VC_Structure::validate( $s, vc_fixture_map(), array() ) );
}
function test_validate_taken_slug() {
$s = vc_fixture_structure();
$s[1]['cities'][] = array( 'id' => '22', 'name' => 'Victoria', 'slug' => 'victoria' );
$errors = VC_Structure::validate( $s, vc_fixture_map(), array( 'victoria' => 'destination "Victoria"' ) );
vc_assert_contains( 'Slug "victoria" is already used by destination "Victoria".', $errors );
}
function test_validate_empty_region() {
$s = vc_fixture_structure();
$s[0]['name'] = '';
vc_assert_contains( 'Region 1 has no name.', VC_Structure::validate( $s, vc_fixture_map(), array() ) );
}
function test_canonical_city_primary() {
vc_assert_same( 'paris', VC_Structure::canonical_city( vc_fixture_structure(), array( '479', '737' ), '479' ) );
}
function test_canonical_city_fallback_order() {
vc_assert_same( 'amsterdam', VC_Structure::canonical_city( vc_fixture_structure(), array( '678', '479', '737' ), '5555' ) );
}
function test_canonical_city_none() {
vc_assert_same( '', VC_Structure::canonical_city( vc_fixture_structure(), array( '5555' ), '' ) );
}
function test_primary_destination_id() {
vc_assert_same( '2', VC_Structure::primary_destination_id( array( array( 'ref' => '1' ), array( 'ref' => '2', 'primary' => true ) ) ) );
vc_assert_same( '', VC_Structure::primary_destination_id( array() ) );
}
function vc_fixture_synced() {
$s = vc_fixture_structure();
$s[0]['term_id'] = 11;
$s[1]['term_id'] = 12;
return $s;
}
function test_rewrite_rules() {
vc_assert_same(
array(
'^europe/page/([0-9]+)/?$' => 'index.php?viator_destination=europe&paged=$matches[1]',
'^europe/?$' => 'index.php?viator_destination=europe',
'^americas/page/([0-9]+)/?$' => 'index.php?viator_destination=americas&paged=$matches[1]',
'^americas/?$' => 'index.php?viator_destination=americas',
'^amsterdam/page/([0-9]+)/?$' => 'index.php?viator_destination=amsterdam&paged=$matches[1]',
'^amsterdam/?$' => 'index.php?viator_destination=amsterdam',
'^amsterdam/([^/]+)/?$' => 'index.php?viator_tour=$matches[1]',
'^paris/page/([0-9]+)/?$' => 'index.php?viator_destination=paris&paged=$matches[1]',
'^paris/?$' => 'index.php?viator_destination=paris',
'^paris/([^/]+)/?$' => 'index.php?viator_tour=$matches[1]',
'^boston/page/([0-9]+)/?$' => 'index.php?viator_destination=boston&paged=$matches[1]',
'^boston/?$' => 'index.php?viator_destination=boston',
'^boston/([^/]+)/?$' => 'index.php?viator_tour=$matches[1]',
),
VC_Structure::rewrite_rules( vc_fixture_synced() )
);
}
function test_rewrite_rules_empty_region() {
$rules = VC_Structure::rewrite_rules( array( array( 'name' => 'Europe', 'slug' => 'europe', 'term_id' => 11, 'cities' => array() ) ) );
vc_assert_same(
array(
'^europe/page/([0-9]+)/?$' => 'index.php?viator_destination=europe&paged=$matches[1]',
'^europe/?$' => 'index.php?viator_destination=europe',
),
$rules
);
}
// Before the structure is ever saved, get() returns the unsynced presets:
// they must not claim /uk/, /europe/, … over existing pages.
function test_rewrite_rules_skip_unsynced_regions() {
vc_assert_same( array(), VC_Structure::rewrite_rules( VC_Structure::default_regions() ) );
}