Complete implementations of server status and user status REST calls
- Fixes #30 - Fixes #31 - Avatars are not yet supported by the data model; blocked by issue #52
This commit is contained in:
parent
3a26c75044
commit
4cded011ff
6 changed files with 104 additions and 16 deletions
|
@ -595,13 +595,22 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
}
|
||||
|
||||
protected function userStatus(array $url, array $data): Response {
|
||||
// FIXME: stub
|
||||
$data = Arsse::$db->userPropertiesGet(Arsse::$user->id);
|
||||
$data = Arsse::$user::propertiesGet(Arsse::$user->id, true);
|
||||
// construct the avatar structure, if an image is available
|
||||
if(isset($data['avatar'])) {
|
||||
$avatar = [
|
||||
'data' => base64_encode($data['avatar']['data']),
|
||||
'mime' => $data['avatar']['type'],
|
||||
];
|
||||
} else {
|
||||
$avatar = null;
|
||||
}
|
||||
// construct the rest of the structure
|
||||
$out = [
|
||||
'userId' => Arsse::$user->id,
|
||||
'displayName' => $data['name'] ?? Arsse::$user->id,
|
||||
'lastLoginTimestamp' => time(),
|
||||
'avatar' => null,
|
||||
'avatar' => $avatar,
|
||||
];
|
||||
return new Response(200, $out);
|
||||
}
|
||||
|
@ -629,12 +638,11 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
}
|
||||
|
||||
protected function serverStatus(array $url, array $data): Response {
|
||||
// FIXME: stub
|
||||
return new Response(200, [
|
||||
'version' => self::VERSION,
|
||||
'arsse_version' => \JKingWeb\Arsse\VERSION,
|
||||
'warnings' => [
|
||||
'improperlyConfiguredCron' => false,
|
||||
'improperlyConfiguredCron' => !\JKingWeb\Arsse\Service::hasCheckedIn(),
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -22,8 +22,12 @@ class Service {
|
|||
return $classes;
|
||||
}
|
||||
|
||||
protected static function interval(): \DateInterval {
|
||||
return new \DateInterval(Arsse::$conf->serviceFrequency); // FIXME: this needs to fall back in case of incorrect input
|
||||
public static function interval(): \DateInterval {
|
||||
try{
|
||||
return new \DateInterval(Arsse::$conf->serviceFrequency);
|
||||
} catch(\Exception $e) {
|
||||
return new \DateInterval("PT2M");
|
||||
}
|
||||
}
|
||||
|
||||
function __construct() {
|
||||
|
@ -32,14 +36,13 @@ class Service {
|
|||
$this->interval = static::interval();
|
||||
}
|
||||
|
||||
function watch(bool $loop = true) {
|
||||
function watch(bool $loop = true): \DateTimeInterface {
|
||||
$t = new \DateTime();
|
||||
do {
|
||||
$this->checkIn();
|
||||
static::cleanupPre();
|
||||
$list = Arsse::$db->feedListStale();
|
||||
if($list) {
|
||||
echo date("H:i:s")." Updating feeds ".json_encode($list)."\n";
|
||||
$this->drv->queue(...$list);
|
||||
$this->drv->exec();
|
||||
$this->drv->clean();
|
||||
|
@ -47,10 +50,13 @@ class Service {
|
|||
unset($list);
|
||||
}
|
||||
$t->add($this->interval);
|
||||
do {
|
||||
@time_sleep_until($t->getTimestamp());
|
||||
} while($t->getTimestamp() > time());
|
||||
if($loop) {
|
||||
do {
|
||||
@time_sleep_until($t->getTimestamp());
|
||||
} while($t->getTimestamp() > time());
|
||||
}
|
||||
} while($loop);
|
||||
return $t;
|
||||
}
|
||||
|
||||
function checkIn(): bool {
|
||||
|
@ -69,8 +75,8 @@ class Service {
|
|||
$limit = new \DateTime();
|
||||
$limit->sub($int);
|
||||
$limit->sub($int);
|
||||
// return whether the check-in time is less than the acceptable limit
|
||||
return ($checkin < $limit);
|
||||
// return whether the check-in time is within the acceptable limit
|
||||
return ($checkin >= $limit);
|
||||
}
|
||||
|
||||
static function cleanupPre(): bool {
|
||||
|
|
|
@ -245,7 +245,7 @@ class User {
|
|||
}
|
||||
}
|
||||
|
||||
public function propertiesGet(string $user): array {
|
||||
public function propertiesGet(string $user, bool $withAvatar = false): array {
|
||||
// prepare default values
|
||||
$domain = null;
|
||||
if(Arsse::$conf->userComposeNames) $domain = substr($user,strrpos($user,"@")+1);
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace JKingWeb\Arsse;
|
|||
use JKingWeb\Arsse\REST\Request;
|
||||
use JKingWeb\Arsse\REST\Response;
|
||||
use JKingWeb\Arsse\Test\Result;
|
||||
use JKingWeb\Arsse\Misc\Date;
|
||||
use JKingWeb\Arsse\Misc\Context;
|
||||
use JKingWeb\Arsse\Db\ExceptionInput;
|
||||
use JKingWeb\Arsse\Db\Transaction;
|
||||
|
@ -260,6 +261,7 @@ class TestNCNV1_2 extends Test\AbstractTest {
|
|||
|
||||
function setUp() {
|
||||
$this->clearData();
|
||||
Arsse::$conf = new Conf();
|
||||
// create a mock user manager
|
||||
Arsse::$user = Phake::mock(User::class);
|
||||
Phake::when(Arsse::$user)->authHTTP->thenReturn(true);
|
||||
|
@ -715,7 +717,7 @@ class TestNCNV1_2 extends Test\AbstractTest {
|
|||
}
|
||||
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), $this->anything())->thenReturn(true);
|
||||
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), (new Context)->editions([]))->thenThrow(new ExceptionInput("tooShort")); // data model function requires one valid integer for multiples
|
||||
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), (new Context)->editions($in[1]))->thenThrow(new ExceptionInput("tooLong")); // data model function for limited to 50 items for multiples
|
||||
Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), (new Context)->editions($in[1]))->thenThrow(new ExceptionInput("tooLong")); // data model function limited to 50 items for multiples
|
||||
$exp = new Response(422);
|
||||
$this->assertEquals($exp, $this->h->dispatch(new Request("PUT", "/items/read/multiple")));
|
||||
$this->assertEquals($exp, $this->h->dispatch(new Request("PUT", "/items/unread/multiple")));
|
||||
|
@ -762,4 +764,21 @@ class TestNCNV1_2 extends Test\AbstractTest {
|
|||
Phake::verify(Arsse::$db)->articleMark(Arsse::$user->id, $unstar, (new Context)->articles($in[2]));
|
||||
Phake::verify(Arsse::$db)->articleMark(Arsse::$user->id, $unstar, (new Context)->articles($in[3]));
|
||||
}
|
||||
|
||||
function testQueryTheServerStatus() {
|
||||
$interval = Service::interval();
|
||||
$valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval);
|
||||
$invalid = $valid->sub($interval)->sub($interval);
|
||||
Phake::when(Arsse::$db)->metaGet("service_last_checkin")->thenReturn(Date::transform($valid, "sql"))->thenReturn(Date::transform($invalid, "sql"));
|
||||
$arr1 = $arr2 = [
|
||||
'version' => REST\NextCloudNews\V1_2::VERSION,
|
||||
'arsse_version' => VERSION,
|
||||
'warnings' => [
|
||||
'improperlyConfiguredCron' => false,
|
||||
]
|
||||
];
|
||||
$arr2['warnings']['improperlyConfiguredCron'] = true;
|
||||
$exp = new Response(200, $arr1);
|
||||
$this->assertEquals($exp, $this->h->dispatch(new Request("GET", "/status")));
|
||||
}
|
||||
}
|
51
tests/Service/TestService.php
Normal file
51
tests/Service/TestService.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace JKingWeb\Arsse;
|
||||
use JKingWeb\Arsse\Misc\Date;
|
||||
use Phake;
|
||||
|
||||
|
||||
class TestService extends Test\AbstractTest {
|
||||
protected $srv;
|
||||
|
||||
function setUp() {
|
||||
$this->clearData();
|
||||
Arsse::$conf = new Conf();
|
||||
Arsse::$db = Phake::mock(Database::class);
|
||||
$this->srv = new Service();
|
||||
}
|
||||
|
||||
function testComputeInterval() {
|
||||
$in = [
|
||||
Arsse::$conf->serviceFrequency,
|
||||
"PT2M",
|
||||
"PT5M",
|
||||
"P2M",
|
||||
"5M",
|
||||
"interval",
|
||||
];
|
||||
foreach($in as $index => $spec) {
|
||||
try{$exp = new \DateInterval($spec);} catch(\Exception $e) {$exp = new \DateInterval("PT2M");}
|
||||
Arsse::$conf->serviceFrequency = $spec;
|
||||
$this->assertEquals($exp, Service::interval(), "Interval #$index '$spec' was not correctly calculated");
|
||||
}
|
||||
}
|
||||
|
||||
function testCheckIn() {
|
||||
$now = time();
|
||||
$this->srv->checkIn();
|
||||
Phake::verify(Arsse::$db)->metaSet("service_last_checkin", Phake::capture($then), "datetime");
|
||||
$this->assertTime($now, $then);
|
||||
}
|
||||
|
||||
function testReportHavingCheckedIn() {
|
||||
// the mock's metaGet() returns null by default
|
||||
$this->assertFalse(Service::hasCheckedIn());
|
||||
$interval = Service::interval();
|
||||
$valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval);
|
||||
$invalid = $valid->sub($interval)->sub($interval);
|
||||
Phake::when(Arsse::$db)->metaGet("service_last_checkin")->thenReturn(Date::transform($valid, "sql"))->thenReturn(Date::transform($invalid, "sql"));
|
||||
$this->assertTrue(Service::hasCheckedIn());
|
||||
$this->assertFalse(Service::hasCheckedIn());
|
||||
}
|
||||
}
|
|
@ -53,5 +53,9 @@
|
|||
<file>REST/NextCloudNews/TestNCNVersionDiscovery.php</file>
|
||||
<file>REST/NextCloudNews/TestNCNV1_2.php</file>
|
||||
</testsuite>
|
||||
<testsuite name="Refresh service">
|
||||
<file>Service/TestService.php</file>
|
||||
</testsuite>
|
||||
|
||||
</testsuites>
|
||||
</phpunit>
|
Loading…
Reference in a new issue