import([ 'userSessionTimeout' => "PT1H", 'userSessionLifetime' => "PT24H", ]); // set up the test data $tz = new \DateTimeZone("UTC"); $nowish = (new Date("now - 1 minute", $tz))->format("Y-m-d H:i:s"); $yesterday = (new Date("now - 1 day", $tz))->format("Y-m-d H:i:s"); $daybefore = (new Date("now - 2 days", $tz))->format("Y-m-d H:i:s"); $daysago = (new Date("now - 7 days", $tz))->format("Y-m-d H:i:s"); $weeksago = (new Date("now - 21 days", $tz))->format("Y-m-d H:i:s"); $soon = (new Date("now + 1 minute", $tz))->format("Y-m-d H:i:s"); $faroff = (new Date("now + 1 hour", $tz))->format("Y-m-d H:i:s"); $this->data = [ 'arsse_users' => [ 'columns' => ["id", "password", "num"], 'rows' => [ ["jane.doe@example.com", "",1], ["john.doe@example.com", "",2], ], ], 'arsse_sessions' => [ 'columns' => ["id", "created", "expires", "user"], 'rows' => [ ["a", $nowish, $faroff, "jane.doe@example.com"], // not expired and recently created, thus kept ["b", $nowish, $soon, "jane.doe@example.com"], // not expired and recently created, thus kept ["c", $daysago, $soon, "jane.doe@example.com"], // created more than a day ago, thus deleted ["d", $nowish, $nowish, "jane.doe@example.com"], // recently created but expired, thus deleted ["e", $daysago, $nowish, "jane.doe@example.com"], // created more than a day ago and expired, thus deleted ], ], 'arsse_tokens' => [ 'columns' => ["id", "class", "user", "expires"], 'rows' => [ ["80fa94c1a11f11e78667001e673b2560", "fever.login", "jane.doe@example.com", $faroff], ["27c6de8da13311e78667001e673b2560", "fever.login", "jane.doe@example.com", $weeksago], // expired ["ab3b3eb8a13311e78667001e673b2560", "class.class", "jane.doe@example.com", null], ["da772f8fa13c11e78667001e673b2560", "class.class", "john.doe@example.com", $soon], ], ], 'arsse_icons' => [ 'columns' => ["id", "url", "orphaned"], 'rows' => [ [1,'http://localhost:8000/Icon/PNG',$daybefore], [2,'http://localhost:8000/Icon/GIF',$daybefore], [3,'http://localhost:8000/Icon/SVG1',null], ], ], 'arsse_feeds' => [ 'columns' => ["id", "url", "title", "orphaned", "size", "icon"], 'rows' => [ [1,"http://example.com/1","",$daybefore,2,null], //latest two articles should be kept [2,"http://example.com/2","",$yesterday,0,2], [3,"http://example.com/3","",null,0,1], [4,"http://example.com/4","",$nowish,0,null], ], ], 'arsse_subscriptions' => [ 'columns' => ["id", "owner", "url", "size", "icon", "deleted", "modified"], 'rows' => [ // first two subscriptions are used for article cleanup tests: the latest two articles should be kept [1,'jane.doe@example.com',"http://example.com/1",2,null,0,$daybefore], [2,'john.doe@example.com',"http://example.com/1",2,null,0,$daybefore], // the other subscriptions are used for subscription cleanup [3,'jane.doe@example.com',"http://example.com/2",0, 2,1,$yesterday], ], ], 'arsse_articles' => [ 'columns' => ["id", "subscription", "url_title_hash", "url_content_hash", "title_content_hash", "modified"], 'rows' => [ [1,1,"","","",$weeksago], // is the latest article, thus is kept [2,1,"","","",$weeksago], // is the second latest article, thus is kept [3,1,"","","",$weeksago], // is starred by one user, thus is kept [4,1,"","","",$weeksago], // does not meet the unread threshold due to a recent mark, thus is kept [5,1,"","","",$daysago], // does not meet the unread threshold due to age, thus is kept [6,1,"","","",$weeksago], // does not meet the read threshold due to a recent mark, thus is kept [7,1,"","","",$weeksago], // meets the unread threshold without marks, thus is deleted [8,1,"","","",$weeksago], // meets the unread threshold even with marks, thus is deleted [9,1,"","","",$weeksago], // meets the read threshold, thus is deleted ], ], 'arsse_editions' => [ 'columns' => ["id", "article"], 'rows' => [ [1,1], [2,2], [3,3], [4,4], [5,5], [6,6], [7,7], [8,8], [9,9], [201,1], [102,2], ], ], 'arsse_marks' => [ 'columns' => ["article", "subscription", "read", "starred", "hidden", "modified"], 'rows' => [ [3,1,0,1,0,$weeksago], [4,1,1,0,0,$daysago], [6,1,1,0,0,$nowish], [6,2,1,0,0,$weeksago], [7,2,0,1,1,$weeksago], // hidden takes precedence over starred [8,1,1,0,0,$weeksago], [9,1,1,0,0,$daysago], [9,2,0,0,1,$daysago], // hidden is the same as read for the purposes of cleanup ], ], ]; } protected function tearDownSeriesCleanup(): void { unset($this->data); } public function testCleanUpDeletedSubscriptions(): void { Arsse::$db->subscriptionCleanup(); $now = gmdate("Y-m-d H:i:s"); $state = $this->primeExpectations($this->data, [ 'arsse_feeds' => ["id","orphaned"], ]); $state['arsse_feeds']['rows'][0][1] = null; unset($state['arsse_feeds']['rows'][1]); $state['arsse_feeds']['rows'][2][1] = $now; $this->compareExpectations(static::$drv, $state); } public function testCleanUpDeletedSubscriptionsWithUnlimitedRetention(): void { Arsse::$conf->import([ 'purgeFeeds' => null, ]); Arsse::$db->subscriptionCleanup(); $now = gmdate("Y-m-d H:i:s"); $state = $this->primeExpectations($this->data, [ 'arsse_feeds' => ["id","orphaned"], ]); $state['arsse_feeds']['rows'][0][1] = null; $state['arsse_feeds']['rows'][2][1] = $now; $this->compareExpectations(static::$drv, $state); } public function testCleanUpOrphanedIcons(): void { Arsse::$db->iconCleanup(); $now = gmdate("Y-m-d H:i:s"); $state = $this->primeExpectations($this->data, [ 'arsse_icons' => ["id","orphaned"], ]); $state['arsse_icons']['rows'][0][1] = null; unset($state['arsse_icons']['rows'][1]); $state['arsse_icons']['rows'][2][1] = $now; $this->compareExpectations(static::$drv, $state); } public function testCleanUpOrphanedIconsWithUnlimitedRetention(): void { Arsse::$conf->import([ 'purgeFeeds' => null, ]); Arsse::$db->iconCleanup(); $now = gmdate("Y-m-d H:i:s"); $state = $this->primeExpectations($this->data, [ 'arsse_icons' => ["id","orphaned"], ]); $state['arsse_icons']['rows'][0][1] = null; $state['arsse_icons']['rows'][2][1] = $now; $this->compareExpectations(static::$drv, $state); } public function testCleanUpOldArticlesWithStandardRetention(): void { Arsse::$db->articleCleanup(); $state = $this->primeExpectations($this->data, [ 'arsse_articles' => ["id"], ]); foreach ([7,8,9] as $id) { unset($state['arsse_articles']['rows'][$id - 1]); } $this->compareExpectations(static::$drv, $state); } public function testCleanUpOldArticlesWithUnlimitedReadRetention(): void { Arsse::$conf->import([ 'purgeArticlesRead' => null, ]); Arsse::$db->articleCleanup(); $state = $this->primeExpectations($this->data, [ 'arsse_articles' => ["id"], ]); foreach ([7,8] as $id) { unset($state['arsse_articles']['rows'][$id - 1]); } $this->compareExpectations(static::$drv, $state); } public function testCleanUpOldArticlesWithUnlimitedUnreadRetention(): void { Arsse::$conf->import([ 'purgeArticlesUnread' => null, ]); Arsse::$db->articleCleanup(); $state = $this->primeExpectations($this->data, [ 'arsse_articles' => ["id"], ]); foreach ([9] as $id) { unset($state['arsse_articles']['rows'][$id - 1]); } $this->compareExpectations(static::$drv, $state); } public function testCleanUpOldArticlesWithUnlimitedRetention(): void { Arsse::$conf->import([ 'purgeArticlesRead' => null, 'purgeArticlesUnread' => null, ]); Arsse::$db->articleCleanup(); $state = $this->primeExpectations($this->data, [ 'arsse_articles' => ["id"], ]); $this->compareExpectations(static::$drv, $state); } public function testCleanUpExpiredSessions(): void { Arsse::$db->sessionCleanup(); $state = $this->primeExpectations($this->data, [ 'arsse_sessions' => ["id"], ]); foreach ([3,4,5] as $id) { unset($state['arsse_sessions']['rows'][$id - 1]); } $this->compareExpectations(static::$drv, $state); } public function testCleanUpExpiredTokens(): void { Arsse::$db->tokenCleanup(); $state = $this->primeExpectations($this->data, [ 'arsse_tokens' => ["id", "class"], ]); foreach ([2] as $id) { unset($state['arsse_tokens']['rows'][$id - 1]); } $this->compareExpectations(static::$drv, $state); } }