136 lines
5.3 KiB
PHP
136 lines
5.3 KiB
PHP
<?php
|
|
namespace Xxx\Tests\Unit;
|
|
|
|
use Xxx\Tests\Support\FakeDb;
|
|
use Xxx\Tests\Support\SiteData;
|
|
use Xxx\Tests\Support\TestCase;
|
|
|
|
// get_count() and get_query() in get_data.lib.php
|
|
class QueryTest extends TestCase {
|
|
protected function setUp(): void {
|
|
parent::setUp();
|
|
SiteData::install(array(
|
|
'xxx' => array(
|
|
array('id' => 1, 'title' => 'Apple', 'author' => 'Zed', 'date' => '2020-01-01 10:00:00'),
|
|
array('id' => 2, 'title' => 'Banana', 'author' => 'Yan', 'date' => '2020-02-01 10:00:00', 'story' => '<p>A cherry story.</p>'),
|
|
array('id' => 3, 'title' => 'Cherry', 'author' => 'Xi', 'date' => '2020-03-01 10:00:00', 'hidden' => '1'),
|
|
),
|
|
'queue' => array(
|
|
array('id' => 10, 'title' => 'Queued', 'date' => '2020-04-01 10:00:00'),
|
|
),
|
|
));
|
|
open_db('open');
|
|
}
|
|
|
|
private function lastQuery(): array {
|
|
return end(FakeDb::$log);
|
|
}
|
|
|
|
public function testVisitorsDoNotCountHiddenStories(): void {
|
|
$this->assertSame('2', get_count());
|
|
$this->assertSame('SELECT COUNT(*) FROM xxx WHERE 1 AND hidden IS NOT TRUE', $this->lastQuery()['sql']);
|
|
}
|
|
|
|
public function testEditorsCountHiddenStories(): void {
|
|
$this->asEditor();
|
|
$this->assertSame('3', get_count());
|
|
$this->assertSame('SELECT COUNT(*) FROM xxx WHERE 1', $this->lastQuery()['sql']);
|
|
}
|
|
|
|
public function testEditorsCountTheQueue(): void {
|
|
$this->asEditor();
|
|
$this->request(array('queue' => '1'));
|
|
$this->assertSame('1', get_count());
|
|
}
|
|
|
|
public function testVisitorsCannotCountTheQueue(): void {
|
|
$this->request(array('queue' => '1'));
|
|
$this->assertSame('2', get_count());
|
|
$this->assertStringContainsString('FROM xxx', $this->lastQuery()['sql']);
|
|
}
|
|
|
|
public function testSearchCountBindsTheTermFourTimes(): void {
|
|
$this->request(array('search' => "cherry' OR '1'='1"));
|
|
get_count();
|
|
$query = $this->lastQuery();
|
|
$this->assertSame("SELECT COUNT(*) FROM xxx WHERE (title LIKE ? OR author LIKE ? OR date LIKE ? OR story LIKE ?) AND hidden IS NOT TRUE", $query['sql']);
|
|
$this->assertSame(array_fill(0, 4, "%cherry' OR '1'='1%"), $query['params']);
|
|
}
|
|
|
|
public function testSearchCountFindsMatches(): void {
|
|
$this->request(array('search' => 'cherry'));
|
|
$this->assertSame('1', get_count()); // Banana's story; Cherry is hidden
|
|
}
|
|
|
|
public function testDefaultListIsNewestFirstWithoutHiddenStories(): void {
|
|
$GLOBALS['num_stories'] = 5;
|
|
$rows = get_query();
|
|
$this->assertSame(array('2', '1'), array_column($rows, 'id'));
|
|
$this->assertSame('SELECT * FROM xxx WHERE 1 AND hidden IS NOT TRUE ORDER BY date desc LIMIT 0 , 5', $this->lastQuery()['sql']);
|
|
$this->assertSame(array(0, 0), array_column($rows, 'queue_url'));
|
|
}
|
|
|
|
public function testEditorsSeeHiddenStories(): void {
|
|
$this->asEditor();
|
|
$GLOBALS['num_stories'] = 5;
|
|
$this->assertSame(array('3', '2', '1'), array_column(get_query(), 'id'));
|
|
}
|
|
|
|
public function testSortOrderStartAndShow(): void {
|
|
$this->request(array('sort' => 'title', 'order' => 'asc', 'start' => '1', 'show' => '1'));
|
|
$rows = get_query();
|
|
$this->assertSame('SELECT * FROM xxx WHERE 1 AND hidden IS NOT TRUE ORDER BY title asc LIMIT 1 , 1', $this->lastQuery()['sql']);
|
|
$this->assertSame(array('Banana'), array_column($rows, 'title'));
|
|
}
|
|
|
|
public function testBadSortAndOrderValuesFallBack(): void {
|
|
$this->request(array('sort' => 'id; DROP TABLE xxx', 'order' => 'desc; --', 'start' => 'x', 'show' => 'y'));
|
|
get_query();
|
|
$this->assertSame('SELECT * FROM xxx WHERE 1 AND hidden IS NOT TRUE ORDER BY date desc LIMIT 0 , 1', $this->lastQuery()['sql']);
|
|
}
|
|
|
|
public function testOneStoryById(): void {
|
|
$rows = get_query('2');
|
|
$this->assertSame('SELECT * FROM xxx WHERE 1 AND hidden IS NOT TRUE AND id = 2 LIMIT 0, 1', $this->lastQuery()['sql']);
|
|
$this->assertSame(array('Banana'), array_column($rows, 'title'));
|
|
}
|
|
|
|
public function testVisitorsCannotOpenAHiddenStory(): void {
|
|
$this->assertSame(array(), get_query('3'));
|
|
}
|
|
|
|
public function testEditorsCanOpenAHiddenStory(): void {
|
|
$this->asEditor();
|
|
$this->assertSame(array('Cherry'), array_column(get_query('3'), 'title'));
|
|
$this->assertSame('SELECT * FROM xxx WHERE 1 AND id = 3 LIMIT 0, 1', $this->lastQuery()['sql']);
|
|
}
|
|
|
|
public function testIdIsCastToAnInteger(): void {
|
|
get_query('2.9');
|
|
$this->assertStringContainsString('AND id = 2 LIMIT', $this->lastQuery()['sql']);
|
|
}
|
|
|
|
public function testNonNumericIdListsStories(): void {
|
|
get_query('2 OR 1=1');
|
|
$this->assertStringNotContainsString('OR 1=1', $this->lastQuery()['sql']);
|
|
$this->assertStringContainsString('ORDER BY', $this->lastQuery()['sql']);
|
|
}
|
|
|
|
public function testSearchListBindsTheTerm(): void {
|
|
$this->request(array('search' => '%_'));
|
|
get_query();
|
|
$query = $this->lastQuery();
|
|
$this->assertStringStartsWith('SELECT * FROM xxx WHERE (title LIKE ? OR author LIKE ? OR date LIKE ? OR story LIKE ?) AND hidden IS NOT TRUE ORDER BY', $query['sql']);
|
|
$this->assertSame(array_fill(0, 4, '%%_%'), $query['params']);
|
|
}
|
|
|
|
public function testQueueRowsAreMarked(): void {
|
|
$this->asEditor();
|
|
$this->request(array('queue' => '1'));
|
|
$GLOBALS['num_stories'] = 5;
|
|
$rows = get_query();
|
|
$this->assertSame(array('10'), array_column($rows, 'id'));
|
|
$this->assertSame(array(1), array_column($rows, 'queue_url'));
|
|
}
|
|
}
|