1<?php 2/** 3 * Test Adapter for Delete Page Guard Plugin 4 * 5 * This file provides a testable version of the plugin by extending the 6 * actual plugin class and making protected methods accessible for testing. 7 * 8 * @license GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html) - see LICENSE.md 9 * @author Johann Duscher <jonny.dee@posteo.net> 10 * @copyright 2025 Johann Duscher 11 */ 12 13// Mock the DokuWiki ActionPlugin class for testing 14if (!class_exists('dokuwiki\Extension\ActionPlugin')) { 15 class ActionPlugin { 16 protected $config = [ 17 'patterns' => "^start$\n^sidebar$\n^users:[^:]+:start$", 18 'match_target' => 'id', 19 'exempt_groups' => 'editors,moderators', 20 'trim_mode' => true 21 ]; 22 23 protected $lang = [ 24 'pattern_redos_warning' => 'Pattern "%s" may cause performance issues', 25 'pattern_too_long' => 'Pattern "%s" is too long (max 1000 chars)', 26 'pattern_invalid_syntax' => 'Pattern "%s" has invalid syntax: %s', 27 'deny_msg' => 'Deleting this page is not allowed.', 28 'config_validation_errors' => 'Some regex patterns have validation errors.' 29 ]; 30 31 public function getConf($key) { 32 return isset($this->config[$key]) ? $this->config[$key] : null; 33 } 34 35 public function getLang($key) { 36 return isset($this->lang[$key]) ? $this->lang[$key] : "[$key]"; 37 } 38 } 39 40 // Create the namespace alias 41 class_alias('ActionPlugin', 'dokuwiki\Extension\ActionPlugin'); 42} 43 44// Mock DokuWiki Event classes 45if (!class_exists('dokuwiki\Extension\Event')) { 46 class Event { 47 public $data = []; 48 public $canPreventDefault = true; 49 } 50 class_alias('Event', 'dokuwiki\Extension\Event'); 51} 52 53if (!class_exists('dokuwiki\Extension\EventHandler')) { 54 class EventHandler { 55 public function register_hook($event, $when, $obj, $method) { 56 // Mock implementation 57 } 58 } 59 class_alias('EventHandler', 'dokuwiki\Extension\EventHandler'); 60} 61 62// Mock DokuWiki constants and functions 63if (!defined('DOKU_INC')) define('DOKU_INC', dirname(__DIR__) . '/'); 64 65// Mock wikiFN function for file path testing 66if (!function_exists('wikiFN')) { 67 function wikiFN($id) { 68 global $conf; 69 $datadir = isset($conf['datadir']) ? $conf['datadir'] : '/var/data'; 70 return $datadir . '/pages/' . str_replace(':', '/', $id) . '.txt'; 71 } 72} 73 74// Mock global $conf 75$GLOBALS['conf'] = [ 76 'datadir' => '/var/data' 77]; 78 79// Include the actual plugin file 80require_once dirname(__DIR__) . '/action.php'; 81 82/** 83 * Testable version of the Delete Page Guard plugin 84 * 85 * Extends the actual plugin class and exposes protected methods for testing. 86 */ 87class TestableDeletePageGuard extends action_plugin_deletepageguard { 88 89 /** 90 * Mock configuration storage 91 */ 92 private $testConfig = [ 93 'patterns' => "^start$\n^sidebar$\n^users:[^:]+:start$", 94 'match_target' => 'id', 95 'exempt_groups' => 'editors,moderators', 96 'trim_mode' => true 97 ]; 98 99 /** 100 * Override getConf to use mock configuration 101 */ 102 public function getConf($key) { 103 return isset($this->testConfig[$key]) ? $this->testConfig[$key] : null; 104 } 105 106 /** 107 * Set test configuration (for testing different modes) 108 */ 109 public function setTestConfig($key, $value) { 110 $this->testConfig[$key] = $value; 111 } 112 113 /** 114 * Override getLang to use mock language strings 115 */ 116 public function getLang($key) { 117 $lang = [ 118 'pattern_redos_warning' => 'Pattern "%s" may cause performance issues', 119 'pattern_too_long' => 'Pattern "%s" is too long (max 1000 chars)', 120 'pattern_invalid_syntax' => 'Pattern "%s" has invalid syntax: %s', 121 'deny_msg' => 'Deleting this page is not allowed.', 122 'config_validation_errors' => 'Some regex patterns have validation errors.' 123 ]; 124 return isset($lang[$key]) ? $lang[$key] : "[$key]"; 125 } 126 127 /** 128 * Expose protected validateRegexPattern method for testing 129 */ 130 public function validateRegexPattern($pattern, $lineNumber = 0) { 131 return parent::validateRegexPattern($pattern, $lineNumber); 132 } 133 134 /** 135 * Expose protected matchesPattern method for testing 136 */ 137 public function matchesPattern($pattern, $target) { 138 return parent::matchesPattern($pattern, $target); 139 } 140 141 /** 142 * Expose protected getRelativeFilePath method for testing 143 */ 144 public function getRelativeFilePath($fullPath, $dataDir) { 145 return parent::getRelativeFilePath($fullPath, $dataDir); 146 } 147}