get_error_message()); } assert_true($activationOutput === '', 'Plugin activation produced unexpected output: '.$activationOutput); } assert_true(is_plugin_active(TEST_PLUGIN), 'Plugin was not activated.'); update_option('mahak_jwt_secret', TEST_SECRET); update_option('mahak_user_identifier', 'email'); update_option('mahak_login_route', 'mahak/login'); update_option('mahak_after_login_route', 'wp-admin/profile.php'); pass('Plugin activated and configured'); } function base64_url_encode(string $value): string { return rtrim(strtr(base64_encode($value), '+/', '-_'), '='); } function make_jwt(array $payload, string $secret): string { $header = base64_url_encode(json_encode(['typ' => 'JWT', 'alg' => 'HS256'], JSON_THROW_ON_ERROR)); $body = base64_url_encode(json_encode($payload, JSON_THROW_ON_ERROR)); $signature = base64_url_encode(hash_hmac('sha256', $header.'.'.$body, $secret, true)); return $header.'.'.$body.'.'.$signature; } function http_request(string $url, string $cookieHeader = ''): array { $headers = "Connection: close\r\n"; if ($cookieHeader !== '') { $headers .= "Cookie: $cookieHeader\r\n"; } $context = stream_context_create([ 'http' => [ 'ignore_errors' => true, 'timeout' => 20, 'follow_location' => 0, 'max_redirects' => 1, 'header' => $headers, ], ]); $body = @file_get_contents($url, false, $context); $responseHeaders = $http_response_header ?? []; $status = 0; if (isset($responseHeaders[0]) && preg_match('/^HTTP\/\S+\s+(\d+)/', $responseHeaders[0], $matches)) { $status = (int) $matches[1]; } return [ 'status' => $status, 'headers' => $responseHeaders, 'body' => $body === false ? '' : $body, ]; } function wait_for_http(): void { for ($attempt = 1; $attempt <= 60; $attempt++) { $response = http_request(TEST_SITE_URL.'/wp-login.php'); if ($response['status'] > 0) { pass('WordPress HTTP server is reachable'); return; } sleep(1); } fail('WordPress HTTP server did not become reachable.'); } function header_contains(array $headers, string $needle): bool { foreach ($headers as $header) { if (stripos($header, $needle) !== false) { return true; } } return false; } function cookie_header_from_response(array $headers): string { $cookies = []; foreach ($headers as $header) { if (stripos($header, 'Set-Cookie:') !== 0) { continue; } $cookie = trim(substr($header, strlen('Set-Cookie:'))); $cookiePair = explode(';', $cookie, 2)[0] ?? ''; if ($cookiePair !== '') { $cookies[] = $cookiePair; } } return implode('; ', $cookies); } function test_valid_authentication(): void { $token = make_jwt([ 'iat' => time() - 10, 'exp' => time() + 300, 'data' => [ 'name' => TEST_NAME, 'email' => TEST_EMAIL, 'mobile' => '9123456789', 'username' => 'mahak-auth-user', ], ], TEST_SECRET); $response = http_request(TEST_SITE_URL.'/mahak/login/?token='.rawurlencode($token)); assert_true($response['status'] === 302, 'Valid authentication request should return HTTP 302.'); assert_true( header_contains($response['headers'], 'Set-Cookie: wordpress_logged_in_'), 'Valid authentication request did not issue a WordPress logged-in cookie.' ); assert_true( header_contains($response['headers'], 'Location: '.TEST_SITE_URL.'/wp-admin/profile.php'), 'Valid authentication request did not redirect to the configured route.' ); $user = get_user_by('email', TEST_EMAIL); assert_true($user !== false, 'Authenticated user was not created.'); assert_true($user->display_name === TEST_NAME, 'Authenticated user display name was not saved.'); $cookieHeader = cookie_header_from_response($response['headers']); $profileResponse = http_request(TEST_SITE_URL.'/wp-admin/profile.php', $cookieHeader); assert_true( $profileResponse['status'] !== 302 || !header_contains($profileResponse['headers'], 'wp-login.php'), 'Issued cookies did not authenticate a follow-up WordPress admin request.' ); pass('Valid JWT creates/logs in user and issued cookies authenticate follow-up request'); } function test_invalid_authentication(): void { $token = make_jwt([ 'iat' => time() - 10, 'exp' => time() + 300, 'data' => [ 'name' => 'Invalid User', 'email' => 'invalid-user@example.test', ], ], TEST_SECRET); $response = http_request(TEST_SITE_URL.'/mahak/login/?token='.rawurlencode($token.'tampered')); assert_true( $response['status'] === 500, 'Invalid authentication request should return HTTP 500. Got HTTP '.$response['status'].' with body: '.substr($response['body'], 0, 200) ); assert_true( !header_contains($response['headers'], 'Set-Cookie: wordpress_logged_in_'), 'Invalid authentication request issued a logged-in cookie.' ); pass('Invalid JWT is rejected without login cookies'); } boot_wordpress(); install_wordpress(); activate_and_configure_plugin(); wait_for_http(); test_valid_authentication(); test_invalid_authentication(); echo "[OK] Authentication integration test passed\n";