mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 13:12:41 +00:00
Implement the TTRSS getLabels operation; fixes #89
This commit is contained in:
parent
2e395f3cec
commit
fbbf751214
4 changed files with 111 additions and 16 deletions
|
@ -937,6 +937,17 @@ class Database {
|
|||
return $this->db->prepare($q->getQuery(), $q->getTypes())->run($q->getValues());
|
||||
}
|
||||
|
||||
public function articleCount(string $user, Context $context = null): int {
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) {
|
||||
throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
||||
}
|
||||
$context = $context ?? new Context;
|
||||
$q = $this->articleQuery($user, $context);
|
||||
$q->pushCTE("selected_articles");
|
||||
$q->setBody("SELECT count(*) from selected_articles");
|
||||
return $this->db->prepare($q->getQuery(), $q->getTypes())->run($q->getValues())->getValue();
|
||||
}
|
||||
|
||||
public function articleMark(string $user, array $data, Context $context = null): bool {
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) {
|
||||
throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
||||
|
@ -1000,17 +1011,6 @@ class Database {
|
|||
return (bool) $out;
|
||||
}
|
||||
|
||||
public function articleCount(string $user, Context $context = null): int {
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) {
|
||||
throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
||||
}
|
||||
$context = $context ?? new Context;
|
||||
$q = $this->articleQuery($user, $context);
|
||||
$q->pushCTE("selected_articles");
|
||||
$q->setBody("SELECT count(*) from selected_articles");
|
||||
return $this->db->prepare($q->getQuery(), $q->getTypes())->run($q->getValues())->getValue();
|
||||
}
|
||||
|
||||
public function articleStarred(string $user): array {
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) {
|
||||
throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
||||
|
@ -1026,6 +1026,20 @@ class Database {
|
|||
)->run($user)->getRow();
|
||||
}
|
||||
|
||||
public function articleLabelsGet(string $user, $id, bool $byName = false): array {
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) {
|
||||
throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
||||
}
|
||||
$id = $this->articleValidateId($user, $id)['article'];
|
||||
$out = $this->db->prepare("SELECT id,name from arsse_labels where owner is ? and exists(select id from arsse_label_members where article is ? and label is arsse_labels.id and assigned is 1)", "str", "int")->run($user, $id)->getAll();
|
||||
if (!$out) {
|
||||
return $out;
|
||||
} else {
|
||||
// flatten the result to return just the label ID or name
|
||||
return array_column($out, !$byName ? "id" : "name");
|
||||
}
|
||||
}
|
||||
|
||||
public function articleCleanup(): bool {
|
||||
$query = $this->db->prepare(
|
||||
"WITH target_feed(id,subs) as (".
|
||||
|
|
|
@ -553,6 +553,27 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
return ($id * -1 - self::LABEL_OFFSET);
|
||||
}
|
||||
|
||||
public function opGetLabels(array $data): array {
|
||||
// this function doesn't complain about invalid article IDs
|
||||
$article = (isset($data['article_id']) && ValueInfo::id($data['article_id'])) ? (int) $data['article_id'] : 0;
|
||||
try {
|
||||
$list = $article ? Arsse::$db->articleLabelsGet(Arsse::$user->id, $article) : [];
|
||||
} catch (ExceptionInput $e) {
|
||||
$list = [];
|
||||
}
|
||||
$out = [];
|
||||
foreach (Arsse::$db->labelList(Arsse::$user->id) as $l) {
|
||||
$out[] = [
|
||||
'id' => $this->labelOut($l['id']),
|
||||
'caption' => $l['name'],
|
||||
'fg_color' => "",
|
||||
'bg_color' => "",
|
||||
'checked' => in_array($l['id'], $list),
|
||||
];
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function opAddLabel(array $data) {
|
||||
$in = [
|
||||
'name' => isset($data['caption']) ? $data['caption'] : "",
|
||||
|
|
|
@ -38,13 +38,13 @@ class TestTinyTinyAPI extends Test\AbstractTest {
|
|||
['id' => 4, 'folder' => 6, 'top_folder' => 3, 'unread' => 6, 'updated' => "2017-10-09 15:58:34", 'favicon' => 'http://example.com/4.png'],
|
||||
];
|
||||
protected $labels = [
|
||||
['id' => 5, 'articles' => 0, 'read' => 0],
|
||||
['id' => 3, 'articles' => 100, 'read' => 94],
|
||||
['id' => 1, 'articles' => 2, 'read' => 0],
|
||||
['id' => 5, 'articles' => 0, 'read' => 0, 'name' => "Interesting"],
|
||||
['id' => 3, 'articles' => 100, 'read' => 94, 'name' => "Fascinating"],
|
||||
['id' => 1, 'articles' => 2, 'read' => 0, 'name' => "Logical"],
|
||||
];
|
||||
protected $usedLabels = [
|
||||
['id' => 3, 'articles' => 100, 'read' => 94],
|
||||
['id' => 1, 'articles' => 2, 'read' => 0],
|
||||
['id' => 3, 'articles' => 100, 'read' => 94, 'name' => "Fascinating"],
|
||||
['id' => 1, 'articles' => 2, 'read' => 0, 'name' => "Logical"],
|
||||
];
|
||||
|
||||
protected function respGood($content = null, $seq = 0): Response {
|
||||
|
@ -768,4 +768,49 @@ class TestTinyTinyAPI extends Test\AbstractTest {
|
|||
];
|
||||
$this->assertResponse($this->respGood($exp), $this->h->dispatch(new Request("POST", "", json_encode($in))));
|
||||
}
|
||||
|
||||
public function testRetrieveLabelList() {
|
||||
$in = [
|
||||
['op' => "getLabels", 'sid' => "PriestsOfSyrinx"],
|
||||
['op' => "getLabels", 'sid' => "PriestsOfSyrinx", 'article_id' => 1],
|
||||
['op' => "getLabels", 'sid' => "PriestsOfSyrinx", 'article_id' => 2],
|
||||
['op' => "getLabels", 'sid' => "PriestsOfSyrinx", 'article_id' => 3],
|
||||
['op' => "getLabels", 'sid' => "PriestsOfSyrinx", 'article_id' => 4],
|
||||
];
|
||||
Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->labels));
|
||||
Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 1)->thenReturn([1,3]);
|
||||
Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 2)->thenReturn([3]);
|
||||
Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 3)->thenReturn([]);
|
||||
Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 4)->thenThrow(new ExceptionInput("idMissing"));
|
||||
$exp = [
|
||||
[
|
||||
['id' => -1025, 'caption' => "Logical", 'fg_color' => "", 'bg_color' => "", 'checked' => false],
|
||||
['id' => -1027, 'caption' => "Fascinating", 'fg_color' => "", 'bg_color' => "", 'checked' => false],
|
||||
['id' => -1029, 'caption' => "Interesting", 'fg_color' => "", 'bg_color' => "", 'checked' => false],
|
||||
],
|
||||
[
|
||||
['id' => -1025, 'caption' => "Logical", 'fg_color' => "", 'bg_color' => "", 'checked' => true],
|
||||
['id' => -1027, 'caption' => "Fascinating", 'fg_color' => "", 'bg_color' => "", 'checked' => true],
|
||||
['id' => -1029, 'caption' => "Interesting", 'fg_color' => "", 'bg_color' => "", 'checked' => false],
|
||||
],
|
||||
[
|
||||
['id' => -1025, 'caption' => "Logical", 'fg_color' => "", 'bg_color' => "", 'checked' => false],
|
||||
['id' => -1027, 'caption' => "Fascinating", 'fg_color' => "", 'bg_color' => "", 'checked' => true],
|
||||
['id' => -1029, 'caption' => "Interesting", 'fg_color' => "", 'bg_color' => "", 'checked' => false],
|
||||
],
|
||||
[
|
||||
['id' => -1025, 'caption' => "Logical", 'fg_color' => "", 'bg_color' => "", 'checked' => false],
|
||||
['id' => -1027, 'caption' => "Fascinating", 'fg_color' => "", 'bg_color' => "", 'checked' => false],
|
||||
['id' => -1029, 'caption' => "Interesting", 'fg_color' => "", 'bg_color' => "", 'checked' => false],
|
||||
],
|
||||
[
|
||||
['id' => -1025, 'caption' => "Logical", 'fg_color' => "", 'bg_color' => "", 'checked' => false],
|
||||
['id' => -1027, 'caption' => "Fascinating", 'fg_color' => "", 'bg_color' => "", 'checked' => false],
|
||||
['id' => -1029, 'caption' => "Interesting", 'fg_color' => "", 'bg_color' => "", 'checked' => false],
|
||||
],
|
||||
];
|
||||
for ($a = 0; $a < sizeof($in); $a++) {
|
||||
$this->assertResponse($this->respGood($exp[$a]), $this->h->dispatch(new Request("POST", "", json_encode($in[$a]))), "Test $a failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -805,4 +805,19 @@ trait SeriesArticle {
|
|||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->editionLatest($this->user);
|
||||
}
|
||||
|
||||
public function testListTheLabelsOfAnArticle() {
|
||||
$this->assertEquals([2,1], Arsse::$db->articleLabelsGet("john.doe@example.com", 1));
|
||||
$this->assertEquals([2], Arsse::$db->articleLabelsGet("john.doe@example.com", 5));
|
||||
$this->assertEquals([], Arsse::$db->articleLabelsGet("john.doe@example.com", 2));
|
||||
$this->assertEquals(["Fascinating","Interesting"], Arsse::$db->articleLabelsGet("john.doe@example.com", 1, true));
|
||||
$this->assertEquals(["Fascinating"], Arsse::$db->articleLabelsGet("john.doe@example.com", 5, true));
|
||||
$this->assertEquals([], Arsse::$db->articleLabelsGet("john.doe@example.com", 2, true));
|
||||
}
|
||||
|
||||
public function testListTheLabelsOfAnArticleWithoutAuthority() {
|
||||
Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||
Arsse::$db->articleLabelsGet("john.doe@example.com", 1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue