calendar-plugin/compatibility-layer/ui_e2e_wp_emulation.php

109 lines
4.6 KiB
PHP
Executable File

#!/usr/bin/env php
<?php
declare(strict_types=1);
function assert_true(bool $cond, string $msg): void
{
if (!$cond) {
fwrite(STDERR, "[FAIL] {$msg}\n");
exit(1);
}
}
function request(string $method, string $route, array $json = [], array $headers = []): array|WP_Error
{
$req = new WP_REST_Request($method, $route, $json, $headers);
return rest_do_request($req);
}
function unwrap(array|WP_Error $res, string $context): array
{
if ($res instanceof WP_Error) {
$status = $res->data['status'] ?? 500;
fwrite(STDERR, "[FAIL] {$context}: {$res->code} {$res->message} ({$status})\n");
exit(1);
}
return $res;
}
require __DIR__ . '/wp_emulation.php';
$html = do_shortcode('[calendar]');
assert_true(str_contains($html, 'cp-login-btn'), 'calendar shortcode should render login button');
assert_true(str_contains($html, 'cp-create-btn'), 'calendar shortcode should render create button');
assert_true(str_contains($html, 'cp-public-list'), 'calendar shortcode should render public list');
assert_true(str_contains($html, 'cp-verify-btn'), 'calendar shortcode should render verify action');
assert_true(str_contains($html, 'cp-reset-request-btn'), 'calendar shortcode should render reset action');
assert_true(str_contains($html, 'cp-future-only'), 'calendar shortcode should render future-only control');
assert_true(str_contains($html, 'cp-theme'), 'calendar shortcode should render theme selector');
assert_true(str_contains($html, 'cp-delete-occ-confirm-btn'), 'calendar shortcode should render delete occurrence control');
$reg = unwrap(request('POST', '/calendar/v1/users/register', [
'email' => 'ui-emu@example.test',
'password' => 'pass12345',
'debug_tokens' => true,
]), 'register');
$verify = (string) ($reg['data']['verify_token'] ?? '');
$userId = (int) ($reg['data']['user']['id'] ?? 0);
assert_true($verify !== '' && $userId > 0, 'registration should provide token/id in debug mode');
unwrap(request('POST', '/calendar/v1/users/verify', ['token' => $verify]), 'verify');
unwrap(request('PATCH', '/calendar/v1/admin/users/' . $userId . '/approve', []), 'approve');
$GLOBALS['wp_user'] = [
'id' => 0,
'email' => '',
'caps' => [],
];
$authHeader = 'Basic ' . base64_encode('ui-emu@example.test:pass12345');
$me = unwrap(request('GET', '/calendar/v1/users/me', [], ['Authorization' => $authHeader]), 'users me');
assert_true((string) ($me['data']['email'] ?? '') === 'ui-emu@example.test', 'me endpoint should resolve basic user');
$created = unwrap(request('POST', '/calendar/v1/events', [
'title' => 'UI Emu Event',
'description' => 'ui flow',
'location' => 'Desk',
'category' => 'Test',
'all_day_event' => false,
'start_datetime' => '2026-06-01T10:00:00+01:00',
'end_datetime' => '2026-06-01T11:00:00+01:00',
'repeat_type' => 'daily',
'repeat_interval' => 1,
'repeat_range_mode' => 'count',
'repeat_count' => 3,
], ['Authorization' => $authHeader]), 'create event');
$eventId = (int) ($created['data']['id'] ?? 0);
assert_true($eventId > 0, 'basic-auth user should be able to create event');
unwrap(request('DELETE', '/calendar/v1/events/' . $eventId . '/occurrences/' . rawurlencode('2026-06-02T10:00:00+01:00'), [], ['Authorization' => $authHeader]), 'delete occurrence');
$occ = unwrap(request('GET', '/calendar/v1/events/' . $eventId . '/occurrences', ['from' => '2026-06-01', 'months' => 1], ['Authorization' => $authHeader]), 'list occurrences');
$days = [];
foreach ((array) ($occ['data'] ?? []) as $row) {
$days[] = substr((string) ($row['occurrence_start'] ?? ''), 0, 10);
}
assert_true(!in_array('2026-06-02', $days, true), 'deleted occurrence should not remain');
unwrap(request('DELETE', '/calendar/v1/events/' . $eventId, [], ['Authorization' => $authHeader]), 'delete event');
$deletedEvent = request('GET', '/calendar/v1/events/' . $eventId, [], ['Authorization' => $authHeader]);
assert_true($deletedEvent instanceof WP_Error, 'deleted event should not resolve');
assert_true(($deletedEvent->data['status'] ?? 0) === 404, 'deleted event fetch should return 404');
$GLOBALS['wp_user'] = [
'id' => 1,
'email' => 'admin@example.test',
'caps' => ['manage_options', 'edit_posts'],
];
unwrap(request('DELETE', '/calendar/v1/admin/users/' . $userId, []), 'remove user');
$GLOBALS['wp_user'] = [
'id' => 0,
'email' => '',
'caps' => [],
];
$meAfterRemove = request('GET', '/calendar/v1/users/me', [], ['Authorization' => $authHeader]);
assert_true($meAfterRemove instanceof WP_Error, 'removed user should not authenticate');
assert_true(($meAfterRemove->data['status'] ?? 0) === 401, 'removed user me endpoint should return 401');
echo "[PASS] ui-e2e wp emulation\n";