setTables(array('xxx' => array( array('id' => 1, 'title' => 'Newest', 'author' => 'Ann', 'date' => '2021-01-03 10:00:00', 'story' => '

First story.

'), array('id' => 2, 'title' => 'Middle', 'author' => 'Bo', 'date' => '2021-01-02 10:00:00', 'story' => '

Second.

'), array('id' => 3, 'title' => 'Secret', 'author' => 'Cy', 'date' => '2021-01-01 10:00:00', 'story' => '

Hidden.

', 'hidden' => '1'), ))); } public function testFrontPageListsTheVisibleStories(): void { $page = $this->get('/'); $this->assertSame(200, $page['status']); $this->assertStringContainsString('Newest', $page['body']); $this->assertStringContainsString('Middle', $page['body']); $this->assertStringNotContainsString('Secret', $page['body']); $this->assertStringNotContainsString('onclick', $page['body']); $this->assertStringEndsWith("\n", $page['body']); } public function testPagesAreNotCached(): void { $page = $this->get('/'); $this->assertStringContainsString('no-store', implode(', ', $page['headers']['cache-control'])); } public function testTheSessionCookieIsSecure(): void { $cookie = $this->header($this->get('/'), 'Set-Cookie'); $this->assertMatchesRegularExpression('/^PHPSESSID=[0-9a-z,-]+;/', $cookie); foreach (array('path=/', 'domain=.site.test', 'secure', 'HttpOnly', 'SameSite=Lax') as $flag) $this->assertStringContainsString("; $flag", $cookie); } // Another site cannot show a page in a hidden frame to trick an editor into a click public function testNoPageCanBeFramed(): void { $paths = array('/', '/article', '/about', '/publish', '/publish/login'); $this->loginAs(); $paths = array_merge($paths, array('/publish/edit', '/publish/addeditor')); foreach ($paths as $path) { $page = $this->get($path); $this->assertSame('DENY', $this->header($page, 'X-Frame-Options'), $path); $this->assertSame("frame-ancestors 'none'", $this->header($page, 'Content-Security-Policy'), $path); } $this->assertSame('DENY', $this->header($this->get('/', array('X-Test-Plain' => '1')), 'X-Frame-Options')); } public function testPlainHttpStartsNoSession(): void { $page = $this->get('/', array('X-Test-Plain' => '1')); $this->assertSame(200, $page['status']); $this->assertArrayNotHasKey('set-cookie', $page['headers']); } public function testNoAnalyticsOrEditorLinksForVisitors(): void { $body = $this->get('/')['body']; $this->assertStringNotContainsString('google-analytics', $body); $this->assertStringNotContainsString('/publish/logout', $body); $this->assertStringNotContainsString('/publish/addeditor', $body); } public function testEditorsSeeHiddenStoriesAndTheirLinks(): void { $token = $this->loginAs(); $body = $this->get('/')['body']; $this->assertStringContainsString('Secret', $body); $this->assertStringContainsString('Logout', $body); $this->assertStringContainsString('Add editor', $body); } public function testTheArticlePageShowsOneStory(): void { $body = $this->get('/article?id=1')['body']; $this->assertStringContainsString('

First story.

', $body); $this->assertStringNotContainsString('Middle', $body); } public function testAHiddenStoryIsNotShown(): void { $body = $this->get('/article?id=3')['body']; $this->assertStringNotContainsString('Hidden.', $body); } public function testSearchFindsStories(): void { $body = $this->get('/article?search=second')['body']; $this->assertStringContainsString('Middle', $body); $this->assertStringNotContainsString('Newest', $body); $this->assertSame(array('%second%'), array_slice($this->queries('/LIKE/')[0]['params'], 0, 1)); } public function testTheSearchTermIsEscaped(): void { $body = $this->get('/article?search=' . rawurlencode('">'))['body']; $this->assertStringNotContainsString('', $body); } public function testThePageRemembersWhereTheVisitorWas(): void { $this->get('/article?id=2'); $this->assertSame('/article?id=2', $this->session()['referrer']); } public function testTheAboutPageLoads(): void { $page = $this->get('/about'); $this->assertSame(200, $page['status']); $this->assertStringContainsString('', $page['body']); // The webmaster's address, at the host of SITE_URL, hidden from harvesters $this->assertStringContainsString('email us', $page['body']); } public function testTheTestsAreNotServed(): void { $this->assertSame(404, $this->get('/tests/php/fixtures/test.env')['status']); } }