diff --git a/lib/SessionStatistics.php b/lib/SessionStatistics.php index 2402b487..e253d7dd 100644 --- a/lib/SessionStatistics.php +++ b/lib/SessionStatistics.php @@ -11,6 +11,7 @@ namespace OCA\ServerInfo; use OCP\AppFramework\Utility\ITimeFactory; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; /** @@ -58,18 +59,21 @@ public function getSessionStatistics(): array { * @param int $offset seconds */ private function getNumberOfActiveUsers(int $offset): int { - $query = $this->connection->getQueryBuilder(); - $query->select('uid') - ->from('authtoken') - ->where($query->expr()->gte( - 'last_activity', - $query->createNamedParameter($this->timeFactory->getTime() - $offset) - ))->groupBy('uid'); + $queryBuilder = $this->connection->getQueryBuilder(); + $queryBuilder->select($queryBuilder->func()->count('userid')) + ->from('preferences') + ->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('login'))) + ->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('lastLogin'))) + ->andwhere($queryBuilder->expr()->gte( + $queryBuilder->expr()->castColumn('configvalue', IQueryBuilder::PARAM_INT), + $queryBuilder->createNamedParameter($this->timeFactory->getTime() - $offset, IQueryBuilder::PARAM_INT), + IQueryBuilder::PARAM_INT, + )); - $result = $query->executeQuery(); - $activeUsers = $result->fetchAll(); + $result = $queryBuilder->executeQuery(); + $activeUsers = (int)$result->fetchOne(); $result->closeCursor(); - return count($activeUsers); + return $activeUsers; } } diff --git a/tests/lib/SessionStatisticsTest.php b/tests/lib/SessionStatisticsTest.php index 57744194..3c83d898 100644 --- a/tests/lib/SessionStatisticsTest.php +++ b/tests/lib/SessionStatisticsTest.php @@ -27,16 +27,15 @@ class SessionStatisticsTest extends TestCase { private ITimeFactory&MockObject $timeFactory; private IDBConnection $connection; private SessionStatistics $instance; - private const TABLE = 'authtoken'; + private int $currentTime; + private const TABLE = 'preferences'; private const OFFSET_5MIN = 300; private const OFFSET_1HOUR = 3600; private const OFFSET_1DAY = 86400; - private const OFFSET_7DAYS = 604800; private const OFFSET_1MONTH = 2592000; private const OFFSET_3MONTHS = 7776000; private const OFFSET_6MONTHS = 15552000; private const OFFSET_1YEAR = 31536000; - private const CURRENT_TIME = 100000000; protected function setUp(): void { @@ -47,54 +46,74 @@ protected function setUp(): void { $this->connection = Server::get(IDBConnection::class); $this->instance = new SessionStatistics($this->connection, $this->timeFactory); + + // when running the tests locally, you may have other lastLogin values in the database. + // using a timestamp in the future to workaround. + $this->currentTime = time() + (400 * 24 * 60 * 60); + + $this->removeDummyValues(); + $this->addDummyValues(); + } + + protected function tearDown(): void { + $this->removeDummyValues(); + } + + protected function removeDummyValues(): void { + $qb = $this->connection->getQueryBuilder(); + $qb->delete('preferences') + ->where($qb->expr()->eq('appid', $qb->createNamedParameter('login'))) + ->andWhere($qb->expr()->eq('configkey', $qb->createNamedParameter('lastLogin'))) + ->andWhere($qb->expr()->like('userid', $qb->createNamedParameter('session-statistics-test%'))); + $qb->executeStatement(); } private function addDummyValues(): void { - $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_5MIN + 1, 10); - $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_1HOUR + 1, 20); - $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_1DAY + 1, 30); - $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_7DAYS + 1, 40); - $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_1MONTH + 1, 50); - $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_3MONTHS + 1, 60); - $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_6MONTHS + 1, 70); - $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_1YEAR + 1, 80); + $this->addDummyValuesWithLastLogin(self::OFFSET_5MIN, 10); + $this->addDummyValuesWithLastLogin(self::OFFSET_5MIN, 11); + $this->addDummyValuesWithLastLogin(self::OFFSET_1HOUR, 20); + $this->addDummyValuesWithLastLogin(self::OFFSET_1HOUR, 21); + $this->addDummyValuesWithLastLogin(self::OFFSET_1HOUR, 22); + $this->addDummyValuesWithLastLogin(self::OFFSET_1DAY, 30); + $this->addDummyValuesWithLastLogin(self::OFFSET_1MONTH, 50); + $this->addDummyValuesWithLastLogin(self::OFFSET_3MONTHS, 60); + $this->addDummyValuesWithLastLogin(self::OFFSET_6MONTHS, 70); + $this->addDummyValuesWithLastLogin(self::OFFSET_1YEAR, 80); + $this->addDummyValuesWithLastLogin(self::OFFSET_1YEAR, 81); + $this->addDummyValuesWithLastLogin(self::OFFSET_1YEAR, 82); } - private function addDummyValuesWithLastLogin($lastActivity, $numOfEntries): void { - for ($i = 0; $i < $numOfEntries; $i++) { - $query = $this->connection->getQueryBuilder(); - $query->insert(self::TABLE) - ->values( - [ - 'uid' => $query->createNamedParameter('user-' . ($numOfEntries + $i % 2)), - 'login_name' => $query->createNamedParameter('user-' . ($numOfEntries + $i % 2)), - 'password' => $query->createNamedParameter('password'), - 'name' => $query->createNamedParameter('user agent'), - 'token' => $query->createNamedParameter('token-' . $this->getUniqueID()), - 'type' => $query->createNamedParameter(0), - 'last_activity' => $query->createNamedParameter($lastActivity), - 'last_check' => $query->createNamedParameter($lastActivity), - ] - ); - $query->executeStatement(); - } + private function addDummyValuesWithLastLogin(int $offset, int $id): void { + $query = $this->connection->getQueryBuilder(); + $query->insert(self::TABLE) + ->values( + [ + 'userid' => $query->createNamedParameter("session-statistics-test$id"), + 'appid' => $query->createNamedParameter('login'), + 'configkey' => $query->createNamedParameter('lastLogin'), + 'configvalue' => $query->createNamedParameter((string)($this->currentTime - $offset + 1)), + 'lazy' => $query->createNamedParameter(0), + 'type' => $query->createNamedParameter(0), + 'flags' => $query->createNamedParameter(0), + ] + ); + $query->executeStatement(); } public function testGetSessionStatistics() { - $this->addDummyValues(); $this->timeFactory->expects($this->any())->method('getTime') - ->willReturn(self::CURRENT_TIME); + ->willReturn($this->currentTime); $result = $this->instance->getSessionStatistics(); $this->assertSame(8, count($result)); - $this->assertSame(2, $result['last5minutes']); - $this->assertSame(4, $result['last1hour']); - $this->assertSame(6, $result['last24hours']); - $this->assertSame(8, $result['last7days']); - $this->assertSame(10, $result['last1month']); - $this->assertSame(12, $result['last3months']); - $this->assertSame(14, $result['last6months']); - $this->assertSame(16, $result['lastyear']); + $this->assertSame(2, $result['last5minutes']); // 2 users in last 5 minutes + $this->assertSame(5, $result['last1hour']); // 2 + 3 users in last hour + $this->assertSame(6, $result['last24hours']); // 2 + 3 + 1 users in last day + $this->assertSame(6, $result['last7days']); // 2 + 3 + 1 + 0 users in last week + $this->assertSame(7, $result['last1month']); // 2 + 3 + 1 + 0 + 1 users in last month + $this->assertSame(8, $result['last3months']); // 2 + 3 + 1 + 0 + 1 + 1 users in last 3 months + $this->assertSame(9, $result['last6months']); // 2 + 3 + 1 + 0 + 1 + 1 + 1 users in last 6 months + $this->assertSame(12, $result['lastyear']); // 2 + 3 + 1 + 0 + 1 + 1 + 1 + 3 users in last year } }