1<?php
2
3namespace dokuwiki\plugin\struct\test;
4
5use dokuwiki\plugin\struct\meta\AccessTable;
6use dokuwiki\plugin\struct\meta\SchemaImporter;
7use dokuwiki\plugin\struct\test\mock\Assignments;
8
9/**
10 * Base class for all struct tests
11 *
12 * It cleans up the database in teardown and provides some useful helper methods
13 *
14 * @package dokuwiki\plugin\struct\test
15 */
16abstract class StructTest extends \DokuWikiTest
17{
18
19    /** @var array alway enable the needed plugins */
20    protected $pluginsEnabled = array('struct', 'sqlite');
21
22    /**
23     * Default teardown
24     *
25     * we always make sure the database is clear
26     */
27    protected function tearDown(): void
28    {
29        parent::tearDown();
30        /** @var \helper_plugin_struct_db $db */
31        $db = plugin_load('helper', 'struct_db');
32        $db->resetDB();
33        Assignments::reset();
34    }
35
36    /**
37     * Creates a schema from one of the available schema files
38     *
39     * @param string $schema
40     * @param string $json base name of the JSON file optional, defaults to $schema
41     * @param int $rev allows to create schemas back in time
42     * @param bool $lookup create as a lookup schema
43     */
44    protected function loadSchemaJSON($schema, $json = '', $rev = 0)
45    {
46        if (!$json) $json = $schema;
47        $file = __DIR__ . "/json/$json.struct.json";
48        if (!file_exists($file)) {
49            throw new \RuntimeException("$file does not exist");
50        }
51
52        $importer = new SchemaImporter($schema, file_get_contents($file));
53
54        if (!$importer->build($rev)) {
55            throw new \RuntimeException("build of $schema from $file failed");
56        }
57    }
58
59    /**
60     * This waits until a new second has passed
61     *
62     * The very first call will return immeadiately, proceeding calls will return
63     * only after at least 1 second after the last call has passed.
64     *
65     * When passing $init=true it will not return immeadiately but use the current
66     * second as initialization. It might still return faster than a second.
67     *
68     * @param bool $init wait from now on, not from last time
69     * @return int new timestamp
70     */
71    protected function waitForTick($init = false)
72    {
73        // this will be in DokuWiki soon
74        if (is_callable('parent::waitForTick')) {
75            return parent::waitForTick($init);
76        }
77
78        static $last = 0;
79        if ($init) $last = time();
80
81        while ($last === $now = time()) {
82            usleep(100000); //recheck in a 10th of a second
83        }
84        $last = $now;
85        return $now;
86    }
87
88    /**
89     * Saves struct data for given page and schema
90     *
91     * Please note that setting the $rev only influences the struct data timestamp,
92     * not the page and changelog entries.
93     *
94     * @param string $page
95     * @param string $table
96     * @param array $data
97     * @param int $rev allows to override the revision timestamp
98     * @param int $rid
99     */
100    protected function saveData($page, $table, $data, $rev = 0, $rid = 0)
101    {
102        saveWikiText($page, "test for $page", "saved for testing");
103        if (AccessTable::isTypePage($page, $rev)) {
104            $access = AccessTable::getPageAccess($table, $page, $rev);
105        } elseif (AccessTable::isTypeSerial($page, $rev)) {
106            $access = AccessTable::getSerialAccess($table, $page);
107        } else {
108            $access = AccessTable::getGlobalAccess($table, $rid);
109        }
110        $access->saveData($data);
111        $assignments = Assignments::getInstance();
112        $assignments->assignPageSchema($page, $table);
113    }
114
115    /**
116     * Access the plugin's English language strings
117     *
118     * @param string $key
119     * @return string
120     */
121    protected function getLang($key)
122    {
123        static $lang = null;
124        if (is_null($lang)) {
125            $lang = array();
126            include(DOKU_PLUGIN . 'struct/lang/en/lang.php');
127        }
128        return $lang[$key];
129    }
130
131    /**
132     * Removes Whitespace
133     *
134     * Makes comparing sql statements a bit simpler as it ignores formatting
135     *
136     * @param $string
137     * @return string
138     */
139    protected function cleanWS($string)
140    {
141        return preg_replace('/\s+/s', '', $string);
142    }
143}
144