Ergänzt AJAX-Livesuche für Seiten, Beiträge und Mediathek
This commit is contained in:
1 parent
11b60fc5d8
commit
41d87f62a4
20 files changed
+703
-311
No files matched your search
@@ -142,6 +142,47 @@ final class EditorSecurityTest extends WebTestCase
|
||||
self::assertSame(1, (int) $this->db->fetchOne('SELECT COUNT(*) FROM page'));
|
||||
}
|
||||
|
||||
public function testLiveSearchDoesNotExposeContentToAnonymousRequests(): void
|
||||
{
|
||||
$client = self::createClient();
|
||||
foreach (['/admin', '/admin/posts', '/admin/media'] as $url) {
|
||||
$client->request('GET', $url.'?q=secret', server: ['HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest', 'HTTP_ACCEPT' => 'application/json']);
|
||||
self::assertResponseRedirects('http://localhost/admin/login');
|
||||
self::assertStringNotContainsString('"html":', $client->getResponse()->getContent());
|
||||
}
|
||||
}
|
||||
|
||||
public function testLiveSearchReturnsFilteredEscapedResultsWithTheSamePermissionsAsTheFullScreen(): void
|
||||
{
|
||||
$client = $this->login('editor');
|
||||
$pages = new PageRepository($this->db, new DocumentValidator(), new SiteSettings($this->db, new MediaLibrary($this->db, $this->path.'-media')));
|
||||
foreach (['page', 'post'] as $type) {
|
||||
$document = DemoContent::pages()['home'];
|
||||
$document['title'] = 'Suchprobe Über uns <img src=x onerror=alert(1)> '.$type;
|
||||
$pages->createPage('suchprobe-'.$type, null, $type, $document);
|
||||
}
|
||||
foreach (['/admin' => 'page', '/admin/posts' => 'post'] as $url => $type) {
|
||||
$headers = ['HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'];
|
||||
$client->request('GET', $url.'?q=suchprobe&status=draft&seite=99&limit=50', server: $headers);
|
||||
self::assertResponseIsSuccessful();
|
||||
self::assertResponseHeaderSame('Content-Type', 'application/json');
|
||||
$data = json_decode($client->getResponse()->getContent(), true, 512, JSON_THROW_ON_ERROR);
|
||||
self::assertSame(1, $data['total']);
|
||||
self::assertSame(['q' => 'suchprobe', 'status' => 'draft', 'limit' => 50, 'seite' => 1], $data['parameters']);
|
||||
self::assertStringContainsString('suchprobe-'.$type, $data['html']);
|
||||
self::assertStringNotContainsString('suchprobe-'.('page' === $type ? 'post' : 'page'), $data['html']);
|
||||
self::assertStringNotContainsString('<img src=x', $data['html']);
|
||||
self::assertStringContainsString('<img src=x', $data['html']);
|
||||
self::assertStringNotContainsString('delete-panel', $data['html']);
|
||||
self::assertStringNotContainsString('<html', $data['html']);
|
||||
self::assertStringContainsString('name="_list_query" value="suchprobe"', $data['html']);
|
||||
$client->request('GET', $url.'?q='.rawurlencode('über uns'), server: $headers);
|
||||
self::assertSame(1, json_decode($client->getResponse()->getContent(), true)['total']);
|
||||
$client->request('GET', $url.'?q=suchprobe&status=published', server: $headers);
|
||||
self::assertSame(0, json_decode($client->getResponse()->getContent(), true)['total']);
|
||||
}
|
||||
}
|
||||
|
||||
public function testCreatingAPageNeedsACsrfTokenAndStartsAsAPrivateDraft(): void
|
||||
{
|
||||
$client = $this->login('editor');
|
||||
@@ -553,7 +594,7 @@ final class EditorSecurityTest extends WebTestCase
|
||||
$client->request('POST', '/admin/media/'.$id, ['_csrf_token' => $token, 'title' => 'Nochmal', 'alt' => '', 'version' => 1]);
|
||||
self::assertResponseRedirects('/admin/media');
|
||||
self::assertSame('Bergblick', $this->db->fetchOne('SELECT title FROM media WHERE id = ?', [$id]));
|
||||
self::assertCount(1, $client->followRedirect()->filter('.notice.error'));
|
||||
self::assertCount(1, $client->followRedirect()->filter('.notice.error:not([hidden])'));
|
||||
} finally {
|
||||
unlink($path);
|
||||
}
|
||||
@@ -593,6 +634,41 @@ final class EditorSecurityTest extends WebTestCase
|
||||
self::assertResponseRedirects('/admin/media?seite=2');
|
||||
}
|
||||
|
||||
public function testMediaLiveSearchCoversAllPagesAltTextArchiveAndLiteralWildcards(): void
|
||||
{
|
||||
$client = $this->login('editor');
|
||||
for ($number = 1; $number <= 27; ++$number) {
|
||||
$this->db->insert('media', [
|
||||
'id' => str_pad((string) $number, 32, '0', STR_PAD_LEFT),
|
||||
'title' => 1 === $number ? 'Seltenes Motiv 100%_!' : 'Bild '.$number,
|
||||
'alt' => 2 === $number ? 'Einzigartiger Alternativtext Äußerer Bereich' : '',
|
||||
'variants' => json_encode([['src' => '/media/x/480', 'width' => 480, 'height' => 320, 'bytes' => 1]]),
|
||||
'archived' => 27 === $number ? 1 : 0,
|
||||
'version' => 1,
|
||||
'created_at' => gmdate('Y-m-d H:i:s', 1700000000 + $number),
|
||||
]);
|
||||
}
|
||||
foreach ([['SELTENES', false, 1], ['ALTERNATIVTEXT', false, 1], ['äußerer', false, 1], ['%_!', false, 1], ['Bild', false, 25], ['Bild', true, 26], ['fehlt', false, 0]] as [$query, $archived, $total]) {
|
||||
$parameters = ['q' => $query, 'archiv' => $archived ? 1 : 0, 'seite' => 99];
|
||||
$client->request('GET', '/admin/media?'.http_build_query($parameters), server: ['HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
|
||||
self::assertResponseIsSuccessful();
|
||||
$data = json_decode($client->getResponse()->getContent(), true, 512, JSON_THROW_ON_ERROR);
|
||||
self::assertSame($total, $data['total'], $query);
|
||||
self::assertSame($total > 24 ? 2 : 1, $data['parameters']['seite']);
|
||||
self::assertStringNotContainsString('<html', $data['html']);
|
||||
}
|
||||
// The HTML fallback uses the same global search, and saving retains its context.
|
||||
$crawler = $client->request('GET', '/admin/media?q=Seltenes');
|
||||
self::assertCount(1, $crawler->filter('.library-tile'));
|
||||
$form = $crawler->filter('.library-tile form')->form(['alt' => 'Geändert']);
|
||||
$client->submit($form);
|
||||
self::assertResponseRedirects('/admin/media?q=Seltenes');
|
||||
self::assertCount(1, $client->followRedirect()->filter('.library-tile'));
|
||||
$crawler = $client->request('GET', '/admin/media?q=0');
|
||||
$client->submit($crawler->filter('.library-tile form')->first()->form(['alt' => 'Ziffernsuche']));
|
||||
self::assertResponseRedirects('/admin/media?q=0');
|
||||
}
|
||||
|
||||
public function testTheMandatoryLegalPagesAreCreatedPublishedAndLinkedEverywhere(): void
|
||||
{
|
||||
$client = $this->login('editor');
|
||||
|
||||
Reference in new issue
Block a user