1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace PhpMyAdmin\Tests\Controllers\Database; |
6
|
|
|
|
7
|
|
|
use PhpMyAdmin\Controllers\Database\EventsController; |
8
|
|
|
use PhpMyAdmin\Database\Events; |
9
|
|
|
use PhpMyAdmin\Http\ServerRequest; |
10
|
|
|
use PhpMyAdmin\Template; |
11
|
|
|
use PhpMyAdmin\Tests\AbstractTestCase; |
12
|
|
|
use PhpMyAdmin\Tests\Stubs\ResponseRenderer; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* @covers \PhpMyAdmin\Controllers\Database\EventsController |
16
|
|
|
* @covers \PhpMyAdmin\Database\Events |
17
|
|
|
*/ |
18
|
|
|
final class EventsControllerTest extends AbstractTestCase |
19
|
|
|
{ |
20
|
|
|
public function testWithEvents(): void |
21
|
|
|
{ |
22
|
|
|
$GLOBALS['server'] = 2; |
23
|
|
|
$GLOBALS['text_dir'] = 'ltr'; |
24
|
|
|
$GLOBALS['PMA_PHP_SELF'] = 'index.php'; |
25
|
|
|
$GLOBALS['db'] = 'test_db'; |
26
|
|
|
$GLOBALS['cfg']['Server']['DisableIS'] = true; |
27
|
|
|
|
28
|
|
|
$dummyDbi = $this->createDbiDummy(); |
29
|
|
|
// phpcs:disable Generic.Files.LineLength.TooLong |
30
|
|
|
$dummyDbi->removeDefaultResults(); |
31
|
|
|
$dummyDbi->addSelectDb('test_db'); |
32
|
|
|
$dummyDbi->addResult( |
33
|
|
|
'SHOW EVENTS FROM `test_db`', |
34
|
|
|
[['test_db', 'test_event', 'definer@localhost', 'ONE TIME', 'ENABLED']], |
35
|
|
|
['Db', 'Name', 'Definer', 'Type', 'Status'], |
36
|
|
|
); |
37
|
|
|
$dummyDbi->addResult('SELECT CURRENT_USER();', [['definer@localhost']], ['CURRENT_USER()']); |
38
|
|
|
$dummyDbi->addResult( |
39
|
|
|
"SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`USER_PRIVILEGES` WHERE GRANTEE='''definer''@''localhost''' AND PRIVILEGE_TYPE='EVENT'", |
40
|
|
|
[['EVENT']], |
41
|
|
|
['PRIVILEGE_TYPE'], |
42
|
|
|
); |
43
|
|
|
$dummyDbi->addResult( |
44
|
|
|
'SHOW GLOBAL VARIABLES LIKE \'event_scheduler\'', |
45
|
|
|
[['event_scheduler', 'OFF']], |
46
|
|
|
['Variable_name', 'Value'], |
47
|
|
|
); |
48
|
|
|
// phpcs:enable |
49
|
|
|
$dbi = $this->createDatabaseInterface($dummyDbi); |
50
|
|
|
$GLOBALS['dbi'] = $dbi; |
51
|
|
|
$response = new ResponseRenderer(); |
52
|
|
|
$template = new Template(); |
53
|
|
|
|
54
|
|
|
(new EventsController( |
55
|
|
|
$response, |
56
|
|
|
$template, |
57
|
|
|
new Events($dbi, $template, $response), |
58
|
|
|
$dbi, |
59
|
|
|
))($this->createStub(ServerRequest::class)); |
60
|
|
|
|
61
|
|
|
$actual = $response->getHTMLResult(); |
62
|
|
|
// phpcs:disable Generic.Files.LineLength.TooLong |
63
|
|
|
$expected = <<<'HTML' |
64
|
|
|
<div class="container-fluid my-3"> |
65
|
|
|
<h2> |
66
|
|
|
<span class="text-nowrap"><img src="themes/dot.gif" title="Events" alt="Events" class="icon ic_b_events"> Events</span> |
67
|
|
|
<a href="index.php?route=/url&url=https%3A%2F%2Fdev.mysql.com%2Fdoc%2Frefman%2F5.7%2Fen%2Fevents.html" target="mysql_doc"><img src="themes/dot.gif" title="Documentation" alt="Documentation" class="icon ic_b_help"></a> |
68
|
|
|
</h2> |
69
|
|
|
|
70
|
|
|
<div class="d-flex flex-wrap my-3"> <div> |
71
|
|
|
<div class="input-group"> |
72
|
|
|
<div class="input-group-text"> |
73
|
|
|
<div class="form-check mb-0"> |
74
|
|
|
<input class="form-check-input checkall_box" type="checkbox" value="" id="checkAllCheckbox" form="rteListForm"> |
75
|
|
|
<label class="form-check-label" for="checkAllCheckbox">Check all</label> |
76
|
|
|
</div> |
77
|
|
|
</div> |
78
|
|
|
<button class="btn btn-outline-secondary" id="bulkActionExportButton" type="submit" name="submit_mult" value="export" form="rteListForm" title="Export"> |
79
|
|
|
<span class="text-nowrap"><img src="themes/dot.gif" title="Export" alt="Export" class="icon ic_b_export"> Export</span> |
80
|
|
|
</button> |
81
|
|
|
<button class="btn btn-outline-secondary" id="bulkActionDropButton" type="submit" name="submit_mult" value="drop" form="rteListForm" title="Drop"> |
82
|
|
|
<span class="text-nowrap"><img src="themes/dot.gif" title="Drop" alt="Drop" class="icon ic_b_drop"> Drop</span> |
83
|
|
|
</button> |
84
|
|
|
</div> |
85
|
|
|
</div> |
86
|
|
|
<div class="ms-auto"> |
87
|
|
|
<a class="ajax add_anchor btn btn-primary" href="index.php?route=/database/events&db=test_db&add_item=1&server=2&lang=en" role="button"> |
88
|
|
|
<span class="text-nowrap"><img src="themes/dot.gif" title="Create new event" alt="Create new event" class="icon ic_b_event_add"> Create new event</span> |
89
|
|
|
</a> |
90
|
|
|
</div> |
91
|
|
|
</div> |
92
|
|
|
|
93
|
|
|
<form id="rteListForm" class="ajax" action="index.php?route=/database/events&server=2&lang=en"> |
94
|
|
|
<input type="hidden" name="db" value="test_db"><input type="hidden" name="server" value="2"><input type="hidden" name="lang" value="en"><input type="hidden" name="token" value="token"> |
95
|
|
|
|
96
|
|
|
<div id="nothing2display" class="hide"> |
97
|
|
|
<div class="alert alert-primary" role="alert"> |
98
|
|
|
<img src="themes/dot.gif" title="" alt="" class="icon ic_s_notice"> There are no events to display. |
99
|
|
|
</div> |
100
|
|
|
|
101
|
|
|
</div> |
102
|
|
|
|
103
|
|
|
<table id="eventsTable" class="table table-striped table-hover w-auto data"> |
104
|
|
|
<thead> |
105
|
|
|
<tr> |
106
|
|
|
<th></th> |
107
|
|
|
<th>Name</th> |
108
|
|
|
<th>Status</th> |
109
|
|
|
<th>Type</th> |
110
|
|
|
<th colspan="3"></th> |
111
|
|
|
</tr> |
112
|
|
|
</thead> |
113
|
|
|
<tbody> |
114
|
|
|
<tr class="hide"><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr> |
115
|
|
|
|
116
|
|
|
<tr> |
117
|
|
|
<td> |
118
|
|
|
<input type="checkbox" class="checkall" name="item_name[]" value="test_event"> |
119
|
|
|
</td> |
120
|
|
|
<td> |
121
|
|
|
<span class="drop_sql hide">DROP EVENT IF EXISTS `test_event`</span> |
122
|
|
|
<strong>test_event</strong> |
123
|
|
|
</td> |
124
|
|
|
<td> |
125
|
|
|
ENABLED |
126
|
|
|
</td> |
127
|
|
|
<td> |
128
|
|
|
ONE TIME |
129
|
|
|
</td> |
130
|
|
|
<td> |
131
|
|
|
<a class="ajax edit_anchor" href="index.php?route=/database/events&db=test_db&edit_item=1&item_name=test_event&server=2&lang=en"> |
132
|
|
|
<span class="text-nowrap"><img src="themes/dot.gif" title="Edit" alt="Edit" class="icon ic_b_edit"> Edit</span> |
133
|
|
|
</a> |
134
|
|
|
</td> |
135
|
|
|
<td> |
136
|
|
|
<a class="ajax export_anchor" href="index.php?route=/database/events&db=test_db&export_item=1&item_name=test_event&server=2&lang=en"> |
137
|
|
|
<span class="text-nowrap"><img src="themes/dot.gif" title="Export" alt="Export" class="icon ic_b_export"> Export</span> |
138
|
|
|
</a> |
139
|
|
|
</td> |
140
|
|
|
<td> |
141
|
|
|
<a href="index.php" data-post="route=/sql&server=2&lang=en&db=test_db&sql_query=DROP+EVENT+IF+EXISTS+%60test_event%60&goto=index.php%3Froute%3D%2Fdatabase%2Fevents%26db%3Dtest_db%26server%3D2%26lang%3Den&server=2&lang=en" class="ajax drop_anchor"><span class="text-nowrap"><img src="themes/dot.gif" title="Drop" alt="Drop" class="icon ic_b_drop"> Drop</span></a> |
142
|
|
|
</td> |
143
|
|
|
</tr> |
144
|
|
|
</tbody> |
145
|
|
|
</table> |
146
|
|
|
</form> |
147
|
|
|
|
148
|
|
|
<div class="card mt-3"> |
149
|
|
|
<div class="card-header">Event scheduler status</div> |
150
|
|
|
<div class="card-body"> |
151
|
|
|
<div class="wrap"> |
152
|
|
|
<div class="wrapper toggleAjax hide"> |
153
|
|
|
<div class="toggleButton"> |
154
|
|
|
<div title="Click to toggle" class="toggle-container off"> |
155
|
|
|
<img src=""> |
156
|
|
|
<table> |
157
|
|
|
<tbody> |
158
|
|
|
<tr> |
159
|
|
|
<td class="toggleOn"> |
160
|
|
|
<span class="hide">index.php?route=/sql&db=test_db&goto=index.php%3Froute%3D%2Fdatabase%2Fevents%26db%3Dtest_db%26server%3D2%26lang%3Den&sql_query=SET+GLOBAL+event_scheduler%3D%22ON%22&server=2&lang=en</span> |
161
|
|
|
<div>ON</div> |
162
|
|
|
</td> |
163
|
|
|
<td><div> </div></td> |
164
|
|
|
<td class="toggleOff"> |
165
|
|
|
<span class="hide">index.php?route=/sql&db=test_db&goto=index.php%3Froute%3D%2Fdatabase%2Fevents%26db%3Dtest_db%26server%3D2%26lang%3Den&sql_query=SET+GLOBAL+event_scheduler%3D%22OFF%22&server=2&lang=en</span> |
166
|
|
|
<div>OFF</div> |
167
|
|
|
</td> |
168
|
|
|
</tr> |
169
|
|
|
</tbody> |
170
|
|
|
</table> |
171
|
|
|
<span class="hide callback">Functions.slidingMessage(data.sql_query);</span> |
172
|
|
|
<span class="hide text_direction">ltr</span> |
173
|
|
|
</div> |
174
|
|
|
</div> |
175
|
|
|
</div> |
176
|
|
|
</div> |
177
|
|
|
</div> |
178
|
|
|
</div> |
179
|
|
|
</div> |
180
|
|
|
|
181
|
|
|
HTML; |
182
|
|
|
// phpcs:enable |
183
|
|
|
|
184
|
|
|
$this->assertSame($expected, $actual); |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
public function testWithoutEvents(): void |
188
|
|
|
{ |
189
|
|
|
$GLOBALS['server'] = 2; |
190
|
|
|
$GLOBALS['text_dir'] = 'ltr'; |
191
|
|
|
$GLOBALS['PMA_PHP_SELF'] = 'index.php'; |
192
|
|
|
$GLOBALS['db'] = 'test_db'; |
193
|
|
|
$GLOBALS['cfg']['Server']['DisableIS'] = true; |
194
|
|
|
|
195
|
|
|
$dummyDbi = $this->createDbiDummy(); |
196
|
|
|
// phpcs:disable Generic.Files.LineLength.TooLong |
197
|
|
|
$dummyDbi->removeDefaultResults(); |
198
|
|
|
$dummyDbi->addSelectDb('test_db'); |
199
|
|
|
$dummyDbi->addResult( |
200
|
|
|
'SHOW EVENTS FROM `test_db`', |
201
|
|
|
[], |
202
|
|
|
['Db', 'Name', 'Definer', 'Type', 'Status'], |
203
|
|
|
); |
204
|
|
|
$dummyDbi->addResult('SELECT CURRENT_USER();', [['definer@localhost']], ['CURRENT_USER()']); |
205
|
|
|
$dummyDbi->addResult( |
206
|
|
|
"SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`USER_PRIVILEGES` WHERE GRANTEE='''definer''@''localhost''' AND PRIVILEGE_TYPE='EVENT'", |
207
|
|
|
[['EVENT']], |
208
|
|
|
['PRIVILEGE_TYPE'], |
209
|
|
|
); |
210
|
|
|
$dummyDbi->addResult( |
211
|
|
|
'SHOW GLOBAL VARIABLES LIKE \'event_scheduler\'', |
212
|
|
|
[['event_scheduler', 'OFF']], |
213
|
|
|
['Variable_name', 'Value'], |
214
|
|
|
); |
215
|
|
|
// phpcs:enable |
216
|
|
|
$dbi = $this->createDatabaseInterface($dummyDbi); |
217
|
|
|
$GLOBALS['dbi'] = $dbi; |
218
|
|
|
$response = new ResponseRenderer(); |
219
|
|
|
$template = new Template(); |
220
|
|
|
|
221
|
|
|
(new EventsController( |
222
|
|
|
$response, |
223
|
|
|
$template, |
224
|
|
|
new Events($dbi, $template, $response), |
225
|
|
|
$dbi, |
226
|
|
|
))($this->createStub(ServerRequest::class)); |
227
|
|
|
|
228
|
|
|
$actual = $response->getHTMLResult(); |
229
|
|
|
// phpcs:disable Generic.Files.LineLength.TooLong |
230
|
|
|
$expected = <<<'HTML' |
231
|
|
|
<div class="container-fluid my-3"> |
232
|
|
|
<h2> |
233
|
|
|
<span class="text-nowrap"><img src="themes/dot.gif" title="Events" alt="Events" class="icon ic_b_events"> Events</span> |
234
|
|
|
<a href="index.php?route=/url&url=https%3A%2F%2Fdev.mysql.com%2Fdoc%2Frefman%2F5.7%2Fen%2Fevents.html" target="mysql_doc"><img src="themes/dot.gif" title="Documentation" alt="Documentation" class="icon ic_b_help"></a> |
235
|
|
|
</h2> |
236
|
|
|
|
237
|
|
|
<div class="d-flex flex-wrap my-3"> |
238
|
|
|
<div> |
239
|
|
|
<a class="ajax add_anchor btn btn-primary" href="index.php?route=/database/events&db=test_db&add_item=1&server=2&lang=en" role="button"> |
240
|
|
|
<span class="text-nowrap"><img src="themes/dot.gif" title="Create new event" alt="Create new event" class="icon ic_b_event_add"> Create new event</span> |
241
|
|
|
</a> |
242
|
|
|
</div> |
243
|
|
|
</div> |
244
|
|
|
|
245
|
|
|
<form id="rteListForm" class="ajax" action="index.php?route=/database/events&server=2&lang=en"> |
246
|
|
|
<input type="hidden" name="db" value="test_db"><input type="hidden" name="server" value="2"><input type="hidden" name="lang" value="en"><input type="hidden" name="token" value="token"> |
247
|
|
|
|
248
|
|
|
<div id="nothing2display"> |
249
|
|
|
<div class="alert alert-primary" role="alert"> |
250
|
|
|
<img src="themes/dot.gif" title="" alt="" class="icon ic_s_notice"> There are no events to display. |
251
|
|
|
</div> |
252
|
|
|
|
253
|
|
|
</div> |
254
|
|
|
|
255
|
|
|
<table id="eventsTable" class="table table-striped table-hover hide w-auto data"> |
256
|
|
|
<thead> |
257
|
|
|
<tr> |
258
|
|
|
<th></th> |
259
|
|
|
<th>Name</th> |
260
|
|
|
<th>Status</th> |
261
|
|
|
<th>Type</th> |
262
|
|
|
<th colspan="3"></th> |
263
|
|
|
</tr> |
264
|
|
|
</thead> |
265
|
|
|
<tbody> |
266
|
|
|
<tr class="hide"><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr> |
267
|
|
|
|
268
|
|
|
</tbody> |
269
|
|
|
</table> |
270
|
|
|
</form> |
271
|
|
|
|
272
|
|
|
<div class="card mt-3"> |
273
|
|
|
<div class="card-header">Event scheduler status</div> |
274
|
|
|
<div class="card-body"> |
275
|
|
|
<div class="wrap"> |
276
|
|
|
<div class="wrapper toggleAjax hide"> |
277
|
|
|
<div class="toggleButton"> |
278
|
|
|
<div title="Click to toggle" class="toggle-container off"> |
279
|
|
|
<img src=""> |
280
|
|
|
<table> |
281
|
|
|
<tbody> |
282
|
|
|
<tr> |
283
|
|
|
<td class="toggleOn"> |
284
|
|
|
<span class="hide">index.php?route=/sql&db=test_db&goto=index.php%3Froute%3D%2Fdatabase%2Fevents%26db%3Dtest_db%26server%3D2%26lang%3Den&sql_query=SET+GLOBAL+event_scheduler%3D%22ON%22&server=2&lang=en</span> |
285
|
|
|
<div>ON</div> |
286
|
|
|
</td> |
287
|
|
|
<td><div> </div></td> |
288
|
|
|
<td class="toggleOff"> |
289
|
|
|
<span class="hide">index.php?route=/sql&db=test_db&goto=index.php%3Froute%3D%2Fdatabase%2Fevents%26db%3Dtest_db%26server%3D2%26lang%3Den&sql_query=SET+GLOBAL+event_scheduler%3D%22OFF%22&server=2&lang=en</span> |
290
|
|
|
<div>OFF</div> |
291
|
|
|
</td> |
292
|
|
|
</tr> |
293
|
|
|
</tbody> |
294
|
|
|
</table> |
295
|
|
|
<span class="hide callback">Functions.slidingMessage(data.sql_query);</span> |
296
|
|
|
<span class="hide text_direction">ltr</span> |
297
|
|
|
</div> |
298
|
|
|
</div> |
299
|
|
|
</div> |
300
|
|
|
</div> |
301
|
|
|
</div> |
302
|
|
|
</div> |
303
|
|
|
</div> |
304
|
|
|
|
305
|
|
|
HTML; |
306
|
|
|
// phpcs:enable |
307
|
|
|
|
308
|
|
|
$this->assertSame($expected, $actual); |
309
|
|
|
} |
310
|
|
|
} |
311
|
|
|
|