1
1
Fork 0
mirror of https://code.mensbeam.com/MensBeam/Arsse.git synced 2024-12-22 21:22:40 +00:00

Last of the article series of tests

This commit is contained in:
J. King 2017-07-05 10:59:13 -04:00
parent d78318bed7
commit c51ee594aa
2 changed files with 77 additions and 30 deletions

View file

@ -86,14 +86,14 @@ class Database {
return $out; return $out;
} }
public function settingGet(string $key) {
return $this->db->prepare("SELECT value from arsse_settings where key is ?", "str")->run($key)->getValue();
}
public function begin(): Db\Transaction { public function begin(): Db\Transaction {
return $this->db->begin(); return $this->db->begin();
} }
public function settingGet(string $key) {
return $this->db->prepare("SELECT value from arsse_settings where key is ?", "str")->run($key)->getValue();
}
public function settingSet(string $key, string $value): bool { public function settingSet(string $key, string $value): bool {
$out = !$this->db->prepare("UPDATE arsse_settings set value = ? where key is ?", "str", "str")->run($value, $key)->changes(); $out = !$this->db->prepare("UPDATE arsse_settings set value = ? where key is ?", "str", "str")->run($value, $key)->changes();
if(!$out) { if(!$out) {
@ -575,7 +575,17 @@ class Database {
public function articleStarredCount(string $user, array $context = []): int { public function articleStarredCount(string $user, array $context = []): int {
if(!Data::$user->authorize($user, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); if(!Data::$user->authorize($user, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
return $this->db->prepare("SELECT count(*) from arsse_marks where owner is ? and starred is 1", "str")->run($user)->getValue(); return $this->db->prepare(
"WITH RECURSIVE
user(user) as (SELECT ?),
subscribed_feeds(id,sub) as (SELECT feed,id from arsse_subscriptions join user on user is owner) ".
"SELECT count(*) from arsse_marks
join user on user is owner
join arsse_articles on arsse_marks.article is arsse_articles.id
join subscribed_feeds on arsse_articles.feed is subscribed_feeds.id
where starred is 1",
"str"
)->run($user)->getValue();
} }
public function editionLatest(string $user, Context $context = null): int { public function editionLatest(string $user, Context $context = null): int {
@ -589,27 +599,12 @@ class Database {
$q->setWhere("arsse_feeds.id is ?", "int", $id); $q->setWhere("arsse_feeds.id is ?", "int", $id);
} else { } else {
$q->setCTE("user(user) as (SELECT ?)", "str", $user); $q->setCTE("user(user) as (SELECT ?)", "str", $user);
if($context->folder()) { $q->setCTE(
// if a folder is specified, make sure it exists "feeds(feed) as (SELECT feed from arsse_subscriptions join user on user is owner)",
$this->folderValidateId($user, $context->folder); [], // binding types
// if it does exist, add a common table expression to list it and its children so that we select from the entire subtree [], // binding values
$q->setCTE("folders(folder) as (SELECT ? union select id from arsse_folders join folders on parent is folder)", "int", $context->folder); "join feeds on arsse_articles.feed is feeds.feed" // join expression
// add another CTE for the subscriptions within the folder );
$q->setCTE(
"feeds(feed) as (SELECT feed from arsse_subscriptions join user on user is owner join folders on arsse_subscription.folder is folders.folder)",
[], // binding types
[], // binding values
"join feeds on arsse_articles.feed is feeds.feed" // join expression
);
} else {
// if no folder is specified, a single CTE is added
$q->setCTE(
"feeds(feed) as (SELECT feed from arsse_subscriptions join user on user is owner)",
[], // binding types
[], // binding values
"join feeds on arsse_articles.feed is feeds.feed" // join expression
);
}
} }
return (int) $this->db->prepare($q)->run()->getValue(); return (int) $this->db->prepare($q)->run()->getValue();
} }
@ -797,7 +792,7 @@ class Database {
arsse_articles.id is ? and arsse_subscriptions.owner is ?", arsse_articles.id is ? and arsse_subscriptions.owner is ?",
"int", "str" "int", "str"
)->run($id, $user)->getRow(); )->run($id, $user)->getRow();
if(!$out) throw new Db\ExceptionInput("idMissing", ["action" => $this->caller(), "field" => "article", 'id' => $id]); if(!$out) throw new Db\ExceptionInput("subjectMissing", ["action" => $this->caller(), "field" => "article", 'id' => $id]);
return $out; return $out;
} }
@ -815,7 +810,7 @@ class Database {
edition is ? and arsse_subscriptions.owner is ?", edition is ? and arsse_subscriptions.owner is ?",
"int", "str" "int", "str"
)->run($id, $user)->getRow(); )->run($id, $user)->getRow();
if(!$out) throw new Db\ExceptionInput("idMissing", ["action" => $this->caller(), "field" => "edition", 'id' => $id]); if(!$out) throw new Db\ExceptionInput("subjectMissing", ["action" => $this->caller(), "field" => "edition", 'id' => $id]);
return $out; return $out;
} }
} }

View file

@ -167,6 +167,7 @@ trait SeriesArticle {
["john.doe@example.net", 20,1,0,'2017-01-01 00:00:00'], ["john.doe@example.net", 20,1,0,'2017-01-01 00:00:00'],
["john.doe@example.net", 3,0,1,'2017-01-01 00:00:00'], ["john.doe@example.net", 3,0,1,'2017-01-01 00:00:00'],
["john.doe@example.net", 4,1,1,'2017-01-01 00:00:00'], ["john.doe@example.net", 4,1,1,'2017-01-01 00:00:00'],
["john.doe@example.net", 12,0,1,'2017-01-01 00:00:00'], // user is no longer subscribed to this article's feed; the star should not be counted in articleStarredCount
] ]
], ],
]; ];
@ -327,12 +328,28 @@ trait SeriesArticle {
$this->compareIds([7,6], (new Context)->reverse(true)->limit(2)->latestEdition(8-1)); $this->compareIds([7,6], (new Context)->reverse(true)->limit(2)->latestEdition(8-1));
} }
function testListArticlesOfAMissingFolder() {
$this->assertException("idMissing", "Db", "ExceptionInput");
Data::$db->articleList($this->user, (new Context)->folder(1));
}
function testListArticlesOfAMissingSubscription() {
$this->assertException("idMissing", "Db", "ExceptionInput");
Data::$db->articleList($this->user, (new Context)->subscription(1));
}
function testListArticlesCheckingProperties() { function testListArticlesCheckingProperties() {
$this->user = "john.doe@example.org"; $this->user = "john.doe@example.org";
Data::$db->dateFormatDefault("unix"); Data::$db->dateFormatDefault("unix");
$this->assertResult($this->matches, Data::$db->articleList($this->user)); $this->assertResult($this->matches, Data::$db->articleList($this->user));
} }
function testListArticlesWithoutAuthority() {
Phake::when(Data::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
Data::$db->articleList($this->user);
}
function testMarkAllArticlesUnread() { function testMarkAllArticlesUnread() {
Data::$db->articleMark($this->user, ['read'=>false]); Data::$db->articleMark($this->user, ['read'=>false]);
$now = $this->dateTransform(time(), "sql"); $now = $this->dateTransform(time(), "sql");
@ -502,7 +519,7 @@ trait SeriesArticle {
} }
function testMarkAMissingArticle() { function testMarkAMissingArticle() {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Data::$db->articleMark($this->user, ['starred'=>true], (new Context)->article(1)); Data::$db->articleMark($this->user, ['starred'=>true], (new Context)->article(1));
} }
@ -546,7 +563,7 @@ trait SeriesArticle {
} }
function testMarkAMissingEdition() { function testMarkAMissingEdition() {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Data::$db->articleMark($this->user, ['starred'=>true], (new Context)->edition(2)); Data::$db->articleMark($this->user, ['starred'=>true], (new Context)->edition(2));
} }
@ -593,4 +610,39 @@ trait SeriesArticle {
$state['arsse_marks']['rows'][] = [$this->user,7,0,1,$now]; $state['arsse_marks']['rows'][] = [$this->user,7,0,1,$now];
$this->compareExpectations($state); $this->compareExpectations($state);
} }
function testMarkArticlesWithoutAuthority() {
Phake::when(Data::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
Data::$db->articleMark($this->user, ['read'=>false]);
}
function testCountStarredArticles() {
$this->assertSame(2, Data::$db->articleStarredCount("john.doe@example.com"));
$this->assertSame(2, Data::$db->articleStarredCount("john.doe@example.org"));
$this->assertSame(2, Data::$db->articleStarredCount("john.doe@example.net"));
$this->assertSame(0, Data::$db->articleStarredCount("jane.doe@example.com"));
}
function testCountStarredArticlesWithoutAuthority() {
Phake::when(Data::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
Data::$db->articleStarredCount($this->user);
}
function testFetchLatestEdition() {
$this->assertSame(1001, Data::$db->editionLatest($this->user));
$this->assertSame(4, Data::$db->editionLatest($this->user, (new Context)->subscription(12)));
}
function testFetchLatestEditionOfMissingSubscription() {
$this->assertException("idMissing", "Db", "ExceptionInput");
Data::$db->editionLatest($this->user, (new Context)->subscription(1));
}
function testFetchLatestEditionWithoutAuthority() {
Phake::when(Data::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
Data::$db->editionLatest($this->user);
}
} }