1
1
Fork 0
mirror of https://code.mensbeam.com/MensBeam/Arsse.git synced 2024-12-23 09:02:41 +00:00
Arsse/tests/cases/Database/SeriesArticle.php
J. King cce1089e10 Handle edge case with folder 0
Folder 0 (the root folder) is a valid, though nonsensical selection:
using it as a positive option is the same as not using the option at
all, and using it as a negative option necessarily yields an empty set.

However, it can in some contexts be validly specified, and so it should
be handled consistently. It had not been previously, but is now.
2019-04-02 19:58:35 -04:00

1047 lines
54 KiB
PHP

<?php
/** @license MIT
* Copyright 2017 J. King, Dustin Wilson et al.
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Context\Context;
use JKingWeb\Arsse\Misc\Date;
use Phake;
trait SeriesArticle {
protected function setUpSeriesArticle() {
$this->data = [
'arsse_users' => [
'columns' => [
'id' => 'str',
'password' => 'str',
],
'rows' => [
["jane.doe@example.com", ""],
["john.doe@example.com", ""],
["john.doe@example.org", ""],
["john.doe@example.net", ""],
],
],
'arsse_feeds' => [
'columns' => [
'id' => "int",
'url' => "str",
'title' => "str",
],
'rows' => [
[1,"http://example.com/1", "Feed 1"],
[2,"http://example.com/2", "Feed 2"],
[3,"http://example.com/3", "Feed 3"],
[4,"http://example.com/4", "Feed 4"],
[5,"http://example.com/5", "Feed 5"],
[6,"http://example.com/6", "Feed 6"],
[7,"http://example.com/7", "Feed 7"],
[8,"http://example.com/8", "Feed 8"],
[9,"http://example.com/9", "Feed 9"],
[10,"http://example.com/10", "Feed 10"],
[11,"http://example.com/11", "Feed 11"],
[12,"http://example.com/12", "Feed 12"],
[13,"http://example.com/13", "Feed 13"],
]
],
'arsse_folders' => [
'columns' => [
'id' => "int",
'owner' => "str",
'parent' => "int",
'name' => "str",
],
'rows' => [
[1, "john.doe@example.com", null, "Technology"],
[2, "john.doe@example.com", 1, "Software"],
[3, "john.doe@example.com", 1, "Rocketry"],
[4, "jane.doe@example.com", null, "Politics"],
[5, "john.doe@example.com", null, "Politics"],
[6, "john.doe@example.com", 2, "Politics"],
[7, "john.doe@example.net", null, "Technology"],
[8, "john.doe@example.net", 7, "Software"],
[9, "john.doe@example.net", null, "Politics"],
]
],
'arsse_tags' => [
'columns' => [
'id' => "int",
'owner' => "str",
'name' => "str",
],
'rows' => [
[1, "john.doe@example.com", "Technology"],
[2, "john.doe@example.com", "Software"],
[3, "john.doe@example.com", "Rocketry"],
[4, "jane.doe@example.com", "Politics"],
[5, "john.doe@example.com", "Politics"],
[6, "john.doe@example.net", "Technology"],
[7, "john.doe@example.net", "Software"],
[8, "john.doe@example.net", "Politics"],
]
],
'arsse_subscriptions' => [
'columns' => [
'id' => "int",
'owner' => "str",
'feed' => "int",
'folder' => "int",
'title' => "str",
],
'rows' => [
[1, "john.doe@example.com",1, null,"Subscription 1"],
[2, "john.doe@example.com",2, null,null],
[3, "john.doe@example.com",3, 1,"Subscription 3"],
[4, "john.doe@example.com",4, 6,null],
[5, "john.doe@example.com",10, 5,"Subscription 5"],
[6, "jane.doe@example.com",1, null,null],
[7, "jane.doe@example.com",10,null,"Subscription 7"],
[8, "john.doe@example.org",11,null,null],
[9, "john.doe@example.org",12,null,"Subscription 9"],
[10,"john.doe@example.org",13,null,null],
[11,"john.doe@example.net",10,null,"Subscription 11"],
[12,"john.doe@example.net",2, 9,null],
[13,"john.doe@example.net",3, 8,"Subscription 13"],
[14,"john.doe@example.net",4, 7,null],
]
],
'arsse_tag_members' => [
'columns' => [
'tag' => "int",
'subscription' => "int",
'assigned' => "bool",
],
'rows' => [
[1,3,1],
[1,4,1],
[2,4,1],
[5,1,0],
[5,4,1],
[5,5,1],
[6,13,1],
[6,14,1],
[7,13,1],
[8,12,1],
],
],
'arsse_articles' => [
'columns' => [
'id' => "int",
'feed' => "int",
'url' => "str",
'title' => "str",
'author' => "str",
'published' => "datetime",
'edited' => "datetime",
'content' => "str",
'guid' => "str",
'url_title_hash' => "str",
'url_content_hash' => "str",
'title_content_hash' => "str",
'modified' => "datetime",
],
'rows' => [
[1,1,null,"Title one", null,null,null,"First article", null,"","","","2000-01-01T00:00:00Z"],
[2,1,null,"Title two", null,null,null,"Second article",null,"","","","2010-01-01T00:00:00Z"],
[3,2,null,"Title three",null,null,null,"Third article", null,"","","","2000-01-01T00:00:00Z"],
[4,2,null,null,"John Doe",null,null,null,null,"","","","2010-01-01T00:00:00Z"],
[5,3,null,null,"John Doe",null,null,null,null,"","","","2000-01-01T00:00:00Z"],
[6,3,null,null,"Jane Doe",null,null,null,null,"","","","2010-01-01T00:00:00Z"],
[7,4,null,null,"Jane Doe",null,null,null,null,"","","","2000-01-01T00:00:00Z"],
[8,4,null,null,null,null,null,null,null,"","","","2010-01-01T00:00:00Z"],
[9,5,null,null,null,null,null,null,null,"","","","2000-01-01T00:00:00Z"],
[10,5,null,null,null,null,null,null,null,"","","","2010-01-01T00:00:00Z"],
[11,6,null,null,null,null,null,null,null,"","","","2000-01-01T00:00:00Z"],
[12,6,null,null,null,null,null,null,null,"","","","2010-01-01T00:00:00Z"],
[13,7,null,null,null,null,null,null,null,"","","","2000-01-01T00:00:00Z"],
[14,7,null,null,null,null,null,null,null,"","","","2010-01-01T00:00:00Z"],
[15,8,null,null,null,null,null,null,null,"","","","2000-01-01T00:00:00Z"],
[16,8,null,null,null,null,null,null,null,"","","","2010-01-01T00:00:00Z"],
[17,9,null,null,null,null,null,null,null,"","","","2000-01-01T00:00:00Z"],
[18,9,null,null,null,null,null,null,null,"","","","2010-01-01T00:00:00Z"],
[19,10,null,null,null,null,null,null,null,"","","","2000-01-01T00:00:00Z"],
[20,10,null,null,null,null,null,null,null,"","","","2010-01-01T00:00:00Z"],
[101,11,'http://example.com/1','Article title 1','','2000-01-01 00:00:00','2000-01-01 00:00:01','<p>Article content 1</p>','e433653cef2e572eee4215fa299a4a5af9137b2cefd6283c85bd69a32915beda','f5cb8bfc1c7396dc9816af212a3e2ac5221585c2a00bf7ccb6aabd95dcfcd6a6','fb0bc8f8cb08913dc5a497db700e327f1d34e4987402687d494a5891f24714d4','18fdd4fa93d693128c43b004399e5c9cea6c261ddfa002518d3669f55d8c2207','2000-01-01 01:00:00'],
[102,11,'http://example.com/2','Article title 2','','2000-01-02 00:00:00','2000-01-02 00:00:02','<p>Article content 2</p>','5be8a5a46ecd52ed132191c8d27fb1af6b3d4edc00234c5d9f8f0e10562ed3b7','0e86d2de822a174fe3c44a466953e63ca1f1a58a19cbf475fce0855d4e3d5153','13075894189c47ffcfafd1dfe7fbb539f7c74a69d35a399b3abf8518952714f9','2abd0a8cba83b8214a66c8f0293ba63e467d720540e29ff8ddcdab069d4f1c9e','2000-01-02 02:00:00'],
[103,12,'http://example.com/3','Article title 3','','2000-01-03 00:00:00','2000-01-03 00:00:03','<p>Article content 3</p>','31a6594500a48b59fcc8a075ce82b946c9c3c782460d088bd7b8ef3ede97ad92','f74b06b240bd08abf4d3fdfc20dba6a6f6eb8b4f1a00e9a617efd63a87180a4b','b278380e984cefe63f0e412b88ffc9cb0befdfa06fdc00bace1da99a8daff406','ad622b31e739cd3a3f3c788991082cf4d2f7a8773773008e75f0572e58cd373b','2000-01-03 03:00:00'],
[104,12,'http://example.com/4','Article title 4','','2000-01-04 00:00:00','2000-01-04 00:00:04','<p>Article content 4</p>','804e517d623390e71497982c77cf6823180342ebcd2e7d5e32da1e55b09dd180','f3615c7f16336d3ea242d35cf3fc17dbc4ee3afb78376bf49da2dd7a5a25dec8','f11c2b4046f207579aeb9c69a8c20ca5461cef49756ccfa5ba5e2344266da3b3','ab2da63276acce431250b18d3d49b988b226a99c7faadf275c90b751aee05be9','2000-01-04 04:00:00'],
[105,13,'http://example.com/5','Article title 5','','2000-01-05 00:00:00','2000-01-05 00:00:05','<p>Article content 5</p>','db3e736c2c492f5def5c5da33ddcbea1824040e9ced2142069276b0a6e291a41','d40da96e39eea6c55948ccbe9b3d275b5f931298288dbe953990c5f496097022','834240f84501b5341d375414718204ec421561f3825d34c22bf9182203e42900','43b970ac6ec5f8a9647b2c7e4eed8b1d7f62e154a95eed748b0294c1256764ba','2000-01-05 05:00:00'],
]
],
'arsse_enclosures' => [
'columns' => [
'article' => "int",
'url' => "str",
'type' => "str",
],
'rows' => [
[102,"http://example.com/text","text/plain"],
[103,"http://example.com/video","video/webm"],
[104,"http://example.com/image","image/svg+xml"],
[105,"http://example.com/audio","audio/ogg"],
]
],
'arsse_editions' => [
'columns' => [
'id' => "int",
'article' => "int",
],
'rows' => [
[1,1],
[2,2],
[3,3],
[4,4],
[5,5],
[6,6],
[7,7],
[8,8],
[9,9],
[10,10],
[11,11],
[12,12],
[13,13],
[14,14],
[15,15],
[16,16],
[17,17],
[18,18],
[19,19],
[20,20],
[101,101],
[102,102],
[103,103],
[104,104],
[105,105],
[202,102],
[203,103],
[204,104],
[205,105],
[305,105],
[1001,20],
]
],
'arsse_marks' => [
'columns' => [
'subscription' => "int",
'article' => "int",
'read' => "bool",
'starred' => "bool",
'modified' => "datetime",
'note' => "str",
],
'rows' => [
[1, 1,1,1,'2000-01-01 00:00:00',''],
[5, 19,1,0,'2016-01-01 00:00:00',''],
[5, 20,0,1,'2005-01-01 00:00:00',''],
[7, 20,1,0,'2010-01-01 00:00:00',''],
[8, 102,1,0,'2000-01-02 02:00:00','Note 2'],
[9, 103,0,1,'2000-01-03 03:00:00','Note 3'],
[9, 104,1,1,'2000-01-04 04:00:00','Note 4'],
[10,105,0,0,'2000-01-05 05:00:00',''],
[11, 19,0,0,'2017-01-01 00:00:00','ook'],
[11, 20,1,0,'2017-01-01 00:00:00','eek'],
[12, 3,0,1,'2017-01-01 00:00:00','ack'],
[12, 4,1,1,'2017-01-01 00:00:00','ach'],
[1, 2,0,0,'2010-01-01 00:00:00','Some Note'],
]
],
'arsse_categories' => [ // author-supplied categories
'columns' => [
'article' => "int",
'name' => "str",
],
'rows' => [
[19,"Fascinating"],
[19,"Logical"],
[20,"Interesting"],
[20,"Logical"],
],
],
'arsse_labels' => [
'columns' => [
'id' => "int",
'owner' => "str",
'name' => "str",
],
'rows' => [
[1,"john.doe@example.com","Interesting"],
[2,"john.doe@example.com","Fascinating"],
[3,"jane.doe@example.com","Boring"],
[4,"john.doe@example.com","Lonely"],
],
],
'arsse_label_members' => [
'columns' => [
'label' => "int",
'article' => "int",
'subscription' => "int",
'assigned' => "bool",
'modified' => "datetime",
],
'rows' => [
[1, 1,1,1,'2000-01-01 00:00:00'],
[2, 1,1,1,'2000-01-01 00:00:00'],
[1,19,5,1,'2000-01-01 00:00:00'],
[2,20,5,1,'2000-01-01 00:00:00'],
[1, 5,3,0,'2000-01-01 00:00:00'],
[2, 5,3,1,'2000-01-01 00:00:00'],
[4, 7,4,0,'2000-01-01 00:00:00'],
[4, 8,4,1,'2015-01-01 00:00:00'],
],
],
];
$this->matches = [
[
'id' => 101,
'url' => 'http://example.com/1',
'title' => 'Article title 1',
'subscription_title' => "Feed 11",
'author' => '',
'content' => '<p>Article content 1</p>',
'guid' => 'e433653cef2e572eee4215fa299a4a5af9137b2cefd6283c85bd69a32915beda',
'published_date' => '2000-01-01 00:00:00',
'edited_date' => '2000-01-01 00:00:01',
'modified_date' => '2000-01-01 01:00:00',
'unread' => 1,
'starred' => 0,
'edition' => 101,
'subscription' => 8,
'fingerprint' => 'f5cb8bfc1c7396dc9816af212a3e2ac5221585c2a00bf7ccb6aabd95dcfcd6a6:fb0bc8f8cb08913dc5a497db700e327f1d34e4987402687d494a5891f24714d4:18fdd4fa93d693128c43b004399e5c9cea6c261ddfa002518d3669f55d8c2207',
'media_url' => null,
'media_type' => null,
'note' => "",
],
[
'id' => 102,
'url' => 'http://example.com/2',
'title' => 'Article title 2',
'subscription_title' => "Feed 11",
'author' => '',
'content' => '<p>Article content 2</p>',
'guid' => '5be8a5a46ecd52ed132191c8d27fb1af6b3d4edc00234c5d9f8f0e10562ed3b7',
'published_date' => '2000-01-02 00:00:00',
'edited_date' => '2000-01-02 00:00:02',
'modified_date' => '2000-01-02 02:00:00',
'unread' => 0,
'starred' => 0,
'edition' => 202,
'subscription' => 8,
'fingerprint' => '0e86d2de822a174fe3c44a466953e63ca1f1a58a19cbf475fce0855d4e3d5153:13075894189c47ffcfafd1dfe7fbb539f7c74a69d35a399b3abf8518952714f9:2abd0a8cba83b8214a66c8f0293ba63e467d720540e29ff8ddcdab069d4f1c9e',
'media_url' => "http://example.com/text",
'media_type' => "text/plain",
'note' => "Note 2",
],
[
'id' => 103,
'url' => 'http://example.com/3',
'title' => 'Article title 3',
'subscription_title' => "Subscription 9",
'author' => '',
'content' => '<p>Article content 3</p>',
'guid' => '31a6594500a48b59fcc8a075ce82b946c9c3c782460d088bd7b8ef3ede97ad92',
'published_date' => '2000-01-03 00:00:00',
'edited_date' => '2000-01-03 00:00:03',
'modified_date' => '2000-01-03 03:00:00',
'unread' => 1,
'starred' => 1,
'edition' => 203,
'subscription' => 9,
'fingerprint' => 'f74b06b240bd08abf4d3fdfc20dba6a6f6eb8b4f1a00e9a617efd63a87180a4b:b278380e984cefe63f0e412b88ffc9cb0befdfa06fdc00bace1da99a8daff406:ad622b31e739cd3a3f3c788991082cf4d2f7a8773773008e75f0572e58cd373b',
'media_url' => "http://example.com/video",
'media_type' => "video/webm",
'note' => "Note 3",
],
[
'id' => 104,
'url' => 'http://example.com/4',
'title' => 'Article title 4',
'subscription_title' => "Subscription 9",
'author' => '',
'content' => '<p>Article content 4</p>',
'guid' => '804e517d623390e71497982c77cf6823180342ebcd2e7d5e32da1e55b09dd180',
'published_date' => '2000-01-04 00:00:00',
'edited_date' => '2000-01-04 00:00:04',
'modified_date' => '2000-01-04 04:00:00',
'unread' => 0,
'starred' => 1,
'edition' => 204,
'subscription' => 9,
'fingerprint' => 'f3615c7f16336d3ea242d35cf3fc17dbc4ee3afb78376bf49da2dd7a5a25dec8:f11c2b4046f207579aeb9c69a8c20ca5461cef49756ccfa5ba5e2344266da3b3:ab2da63276acce431250b18d3d49b988b226a99c7faadf275c90b751aee05be9',
'media_url' => "http://example.com/image",
'media_type' => "image/svg+xml",
'note' => "Note 4",
],
[
'id' => 105,
'url' => 'http://example.com/5',
'title' => 'Article title 5',
'subscription_title' => "Feed 13",
'author' => '',
'content' => '<p>Article content 5</p>',
'guid' => 'db3e736c2c492f5def5c5da33ddcbea1824040e9ced2142069276b0a6e291a41',
'published_date' => '2000-01-05 00:00:00',
'edited_date' => '2000-01-05 00:00:05',
'modified_date' => '2000-01-05 05:00:00',
'unread' => 1,
'starred' => 0,
'edition' => 305,
'subscription' => 10,
'fingerprint' => 'd40da96e39eea6c55948ccbe9b3d275b5f931298288dbe953990c5f496097022:834240f84501b5341d375414718204ec421561f3825d34c22bf9182203e42900:43b970ac6ec5f8a9647b2c7e4eed8b1d7f62e154a95eed748b0294c1256764ba',
'media_url' => "http://example.com/audio",
'media_type' => "audio/ogg",
'note' => "",
],
];
$this->fields = [
"id", "subscription", "feed", "modified_date", "marked_date", "unread", "starred", "edition", "edited_date",
"url", "title", "subscription_title", "author", "guid", "published_date", "fingerprint",
"content", "media_url", "media_type",
"note",
];
$this->checkTables = ['arsse_marks' => ["subscription","article","read","starred","modified","note"],];
$this->user = "john.doe@example.net";
}
protected function tearDownSeriesArticle() {
unset($this->data, $this->matches, $this->fields, $this->checkTables, $this->user);
}
/** @dataProvider provideContextMatches */
public function testListArticlesCheckingContext(Context $c, array $exp) {
$ids = array_column($ids = Arsse::$db->articleList("john.doe@example.com", $c)->getAll(), "id");
sort($ids);
sort($exp);
$this->assertEquals($exp, $ids);
}
public function provideContextMatches() {
return [
'Blank context' => [new Context, [1,2,3,4,5,6,7,8,19,20]],
'Folder tree' => [(new Context)->folder(1), [5,6,7,8]],
'Entire folder tree' => [(new Context)->folder(0), [1,2,3,4,5,6,7,8,19,20]],
'Leaf folder' => [(new Context)->folder(6), [7,8]],
'Root folder only' => [(new Context)->folderShallow(0), [1,2,3,4]],
'Shallow folder' => [(new Context)->folderShallow(1), [5,6]],
'Multiple shallow folders' => [(new Context)->foldersShallow([1,6]), [5,6,7,8]],
'Subscription' => [(new Context)->subscription(5), [19,20]],
'Multiple subscriptions' => [(new Context)->subscriptions([4,5]), [7,8,19,20]],
'Unread' => [(new Context)->subscription(5)->unread(true), [20]],
'Read' => [(new Context)->subscription(5)->unread(false), [19]],
'Starred' => [(new Context)->starred(true), [1,20]],
'Unstarred' => [(new Context)->starred(false), [2,3,4,5,6,7,8,19]],
'Starred and Read' => [(new Context)->starred(true)->unread(false), [1]],
'Starred and Read in subscription' => [(new Context)->starred(true)->unread(false)->subscription(5), []],
'Annotated' => [(new Context)->annotated(true), [2]],
'Not annotated' => [(new Context)->annotated(false), [1,3,4,5,6,7,8,19,20]],
'Labelled' => [(new Context)->labelled(true), [1,5,8,19,20]],
'Not labelled' => [(new Context)->labelled(false), [2,3,4,6,7]],
'Not after edition 999' => [(new Context)->subscription(5)->latestEdition(999), [19]],
'Not after edition 19' => [(new Context)->subscription(5)->latestEdition(19), [19]],
'Not before edition 999' => [(new Context)->subscription(5)->oldestEdition(999), [20]],
'Not before edition 1001' => [(new Context)->subscription(5)->oldestEdition(1001), [20]],
'Not after article 3' => [(new Context)->latestArticle(3), [1,2,3]],
'Not before article 19' => [(new Context)->oldestArticle(19), [19,20]],
'Modified by author since 2005' => [(new Context)->modifiedSince("2005-01-01T00:00:00Z"), [2,4,6,8,20]],
'Modified by author since 2010' => [(new Context)->modifiedSince("2010-01-01T00:00:00Z"), [2,4,6,8,20]],
'Not modified by author since 2005' => [(new Context)->notModifiedSince("2005-01-01T00:00:00Z"), [1,3,5,7,19]],
'Not modified by author since 2000' => [(new Context)->notModifiedSince("2000-01-01T00:00:00Z"), [1,3,5,7,19]],
'Marked or labelled since 2014' => [(new Context)->markedSince("2014-01-01T00:00:00Z"), [8,19]],
'Marked or labelled since 2010' => [(new Context)->markedSince("2010-01-01T00:00:00Z"), [2,4,6,8,19,20]],
'Not marked or labelled since 2014' => [(new Context)->notMarkedSince("2014-01-01T00:00:00Z"), [1,2,3,4,5,6,7,20]],
'Not marked or labelled since 2005' => [(new Context)->notMarkedSince("2005-01-01T00:00:00Z"), [1,3,5,7]],
'Marked or labelled between 2000 and 2015' => [(new Context)->markedSince("2000-01-01T00:00:00Z")->notMarkedSince("2015-12-31T23:59:59Z"), [1,2,3,4,5,6,7,8,20]],
'Marked or labelled in 2010' => [(new Context)->markedSince("2010-01-01T00:00:00Z")->notMarkedSince("2010-12-31T23:59:59Z"), [2,4,6,20]],
'Paged results' => [(new Context)->limit(2)->oldestEdition(4), [4,5]],
'Reversed paged results' => [(new Context)->limit(2)->latestEdition(7)->reverse(true), [7,6]],
'With label ID 1' => [(new Context)->label(1), [1,19]],
'With label ID 2' => [(new Context)->label(2), [1,5,20]],
'With label ID 1 or 2' => [(new Context)->labels([1,2]), [1,5,19,20]],
'With label "Interesting"' => [(new Context)->labelName("Interesting"), [1,19]],
'With label "Fascinating"' => [(new Context)->labelName("Fascinating"), [1,5,20]],
'With label "Interesting" or "Fascinating"' => [(new Context)->labelNames(["Interesting","Fascinating"]), [1,5,19,20]],
'Article ID 20' => [(new Context)->article(20), [20]],
'Edition ID 1001' => [(new Context)->edition(1001), [20]],
'Multiple articles' => [(new Context)->articles([1,20,50]), [1,20]],
'Multiple starred articles' => [(new Context)->articles([1,2,3])->starred(true), [1]],
'Multiple unstarred articles' => [(new Context)->articles([1,2,3])->starred(false), [2,3]],
'Multiple articles' => [(new Context)->articles([1,20,50]), [1,20]],
'Multiple editions' => [(new Context)->editions([1,1001,50]), [1,20]],
'150 articles' => [(new Context)->articles(range(1, Database::LIMIT_SET_SIZE * 3)), [1,2,3,4,5,6,7,8,19,20]],
'Search title or content 1' => [(new Context)->searchTerms(["Article"]), [1,2,3]],
'Search title or content 2' => [(new Context)->searchTerms(["one", "first"]), [1]],
'Search title or content 3' => [(new Context)->searchTerms(["one first"]), []],
'Search title 1' => [(new Context)->titleTerms(["two"]), [2]],
'Search title 2' => [(new Context)->titleTerms(["title two"]), [2]],
'Search title 3' => [(new Context)->titleTerms(["two", "title"]), [2]],
'Search title 4' => [(new Context)->titleTerms(["two title"]), []],
'Search note 1' => [(new Context)->annotationTerms(["some"]), [2]],
'Search note 2' => [(new Context)->annotationTerms(["some Note"]), [2]],
'Search note 3' => [(new Context)->annotationTerms(["note", "some"]), [2]],
'Search note 4' => [(new Context)->annotationTerms(["some", "sauce"]), []],
'Search author 1' => [(new Context)->authorTerms(["doe"]), [4,5,6,7]],
'Search author 2' => [(new Context)->authorTerms(["jane doe"]), [6,7]],
'Search author 3' => [(new Context)->authorTerms(["doe", "jane"]), [6,7]],
'Search author 4' => [(new Context)->authorTerms(["doe jane"]), []],
'Folder tree 1 excluding subscription 4' => [(new Context)->not->subscription(4)->folder(1), [5,6]],
'Folder tree 1 excluding articles 7 and 8' => [(new Context)->folder(1)->not->articles([7,8]), [5,6]],
'Folder tree 1 excluding no articles' => [(new Context)->folder(1)->not->articles([]), [5,6,7,8]],
'Marked or labelled between 2000 and 2015 excluding in 2010' => [(new Context)->markedSince("2000-01-01T00:00:00Z")->notMarkedSince("2015-12-31T23:59:59")->not->markedSince("2010-01-01T00:00:00Z")->not->notMarkedSince("2010-12-31T23:59:59Z"), [1,3,5,7,8]],
'Search with exclusion' => [(new Context)->searchTerms(["Article"])->not->searchTerms(["one", "two"]), [3]],
'Excluded folder tree' => [(new Context)->not->folder(1), [1,2,3,4,19,20]],
'Excluding label ID 2' => [(new Context)->not->label(2), [2,3,4,6,7,8,19]],
'Excluding label "Fascinating"' => [(new Context)->not->labelName("Fascinating"), [2,3,4,6,7,8,19]],
'Search 501 terms' => [(new Context)->searchTerms(array_merge(range(1,500),[str_repeat("a", 1000)])), []],
'With tag ID 1' => [(new Context)->tag(1), [5,6,7,8]],
'With tag ID 5' => [(new Context)->tag(5), [7,8,19,20]],
'With tag ID 1 or 5' => [(new Context)->tags([1,5]), [5,6,7,8,19,20]],
'With tag "Technology"' => [(new Context)->tagName("Technology"), [5,6,7,8]],
'With tag "Politics"' => [(new Context)->tagName("Politics"), [7,8,19,20]],
'With tag "Technology" or "Politics"' => [(new Context)->tagNames(["Technology","Politics"]), [5,6,7,8,19,20]],
'Excluding tag ID 1' => [(new Context)->not->tag(1), [1,2,3,4,19,20]],
'Excluding tag ID 5' => [(new Context)->not->tag(5), [1,2,3,4,5,6]],
'Excluding tag "Technology"' => [(new Context)->not->tagName("Technology"), [1,2,3,4,19,20]],
'Excluding tag "Politics"' => [(new Context)->not->tagName("Politics"), [1,2,3,4,5,6]],
'Excluding entire folder tree' => [(new Context)->not->folder(0), []],
];
}
public function testRetrieveArticleIdsForEditions() {
$exp = [
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
11 => 11,
12 => 12,
13 => 13,
14 => 14,
15 => 15,
16 => 16,
17 => 17,
18 => 18,
19 => 19,
20 => 20,
101 => 101,
102 => 102,
103 => 103,
104 => 104,
105 => 105,
202 => 102,
203 => 103,
204 => 104,
205 => 105,
305 => 105,
1001 => 20,
];
$this->assertEquals($exp, Arsse::$db->editionArticle(...range(1, 1001)));
}
public function testListArticlesOfAMissingFolder() {
$this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->articleList($this->user, (new Context)->folder(1));
}
public function testListArticlesOfAMissingSubscription() {
$this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->articleList($this->user, (new Context)->subscription(1));
}
public function testListArticlesCheckingProperties() {
$this->user = "john.doe@example.org";
// check that the different fieldset groups return the expected columns
foreach ($this->fields as $column) {
$test = array_keys(Arsse::$db->articleList($this->user, (new Context)->article(101), [$column])->getRow());
$this->assertEquals([$column], $test);
}
// check that an unknown field is silently ignored
$columns = array_merge($this->fields, ["unknown_column", "bogus_column"]);
$test = array_keys(Arsse::$db->articleList($this->user, (new Context)->article(101), $columns)->getRow());
$this->assertEquals($this->fields, $test);
}
public function testListArticlesWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleList($this->user);
}
public function testMarkNothing() {
$this->assertSame(0, Arsse::$db->articleMark($this->user, []));
}
public function testMarkAllArticlesUnread() {
Arsse::$db->articleMark($this->user, ['read'=>false]);
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][9][2] = 0;
$state['arsse_marks']['rows'][9][4] = $now;
$state['arsse_marks']['rows'][11][2] = 0;
$state['arsse_marks']['rows'][11][4] = $now;
$this->compareExpectations($state);
}
public function testMarkAllArticlesRead() {
Arsse::$db->articleMark($this->user, ['read'=>true]);
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][8][2] = 1;
$state['arsse_marks']['rows'][8][4] = $now;
$state['arsse_marks']['rows'][10][2] = 1;
$state['arsse_marks']['rows'][10][4] = $now;
$state['arsse_marks']['rows'][] = [13,5,1,0,$now,''];
$state['arsse_marks']['rows'][] = [13,6,1,0,$now,''];
$state['arsse_marks']['rows'][] = [14,7,1,0,$now,''];
$state['arsse_marks']['rows'][] = [14,8,1,0,$now,''];
$this->compareExpectations($state);
}
public function testMarkAllArticlesUnstarred() {
Arsse::$db->articleMark($this->user, ['starred'=>false]);
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][10][3] = 0;
$state['arsse_marks']['rows'][10][4] = $now;
$state['arsse_marks']['rows'][11][3] = 0;
$state['arsse_marks']['rows'][11][4] = $now;
$this->compareExpectations($state);
}
public function testMarkAllArticlesStarred() {
Arsse::$db->articleMark($this->user, ['starred'=>true]);
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][8][3] = 1;
$state['arsse_marks']['rows'][8][4] = $now;
$state['arsse_marks']['rows'][9][3] = 1;
$state['arsse_marks']['rows'][9][4] = $now;
$state['arsse_marks']['rows'][] = [13,5,0,1,$now,''];
$state['arsse_marks']['rows'][] = [13,6,0,1,$now,''];
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
$state['arsse_marks']['rows'][] = [14,8,0,1,$now,''];
$this->compareExpectations($state);
}
public function testMarkAllArticlesUnreadAndUnstarred() {
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>false]);
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][9][2] = 0;
$state['arsse_marks']['rows'][9][4] = $now;
$state['arsse_marks']['rows'][10][3] = 0;
$state['arsse_marks']['rows'][10][4] = $now;
$state['arsse_marks']['rows'][11][2] = 0;
$state['arsse_marks']['rows'][11][3] = 0;
$state['arsse_marks']['rows'][11][4] = $now;
$this->compareExpectations($state);
}
public function testMarkAllArticlesReadAndStarred() {
Arsse::$db->articleMark($this->user, ['read'=>true,'starred'=>true]);
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][8][2] = 1;
$state['arsse_marks']['rows'][8][3] = 1;
$state['arsse_marks']['rows'][8][4] = $now;
$state['arsse_marks']['rows'][9][3] = 1;
$state['arsse_marks']['rows'][9][4] = $now;
$state['arsse_marks']['rows'][10][2] = 1;
$state['arsse_marks']['rows'][10][4] = $now;
$state['arsse_marks']['rows'][] = [13,5,1,1,$now,''];
$state['arsse_marks']['rows'][] = [13,6,1,1,$now,''];
$state['arsse_marks']['rows'][] = [14,7,1,1,$now,''];
$state['arsse_marks']['rows'][] = [14,8,1,1,$now,''];
$this->compareExpectations($state);
}
public function testMarkAllArticlesUnreadAndStarred() {
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true]);
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][8][3] = 1;
$state['arsse_marks']['rows'][8][4] = $now;
$state['arsse_marks']['rows'][9][2] = 0;
$state['arsse_marks']['rows'][9][3] = 1;
$state['arsse_marks']['rows'][9][4] = $now;
$state['arsse_marks']['rows'][11][2] = 0;
$state['arsse_marks']['rows'][11][4] = $now;
$state['arsse_marks']['rows'][] = [13,5,0,1,$now,''];
$state['arsse_marks']['rows'][] = [13,6,0,1,$now,''];
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
$state['arsse_marks']['rows'][] = [14,8,0,1,$now,''];
$this->compareExpectations($state);
}
public function testMarkAllArticlesReadAndUnstarred() {
Arsse::$db->articleMark($this->user, ['read'=>true,'starred'=>false]);
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][8][2] = 1;
$state['arsse_marks']['rows'][8][4] = $now;
$state['arsse_marks']['rows'][10][2] = 1;
$state['arsse_marks']['rows'][10][3] = 0;
$state['arsse_marks']['rows'][10][4] = $now;
$state['arsse_marks']['rows'][11][3] = 0;
$state['arsse_marks']['rows'][11][4] = $now;
$state['arsse_marks']['rows'][] = [13,5,1,0,$now,''];
$state['arsse_marks']['rows'][] = [13,6,1,0,$now,''];
$state['arsse_marks']['rows'][] = [14,7,1,0,$now,''];
$state['arsse_marks']['rows'][] = [14,8,1,0,$now,''];
$this->compareExpectations($state);
}
public function testSetNoteForAllArticles() {
Arsse::$db->articleMark($this->user, ['note'=>"New note"]);
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][8][5] = "New note";
$state['arsse_marks']['rows'][8][4] = $now;
$state['arsse_marks']['rows'][9][5] = "New note";
$state['arsse_marks']['rows'][9][4] = $now;
$state['arsse_marks']['rows'][10][5] = "New note";
$state['arsse_marks']['rows'][10][4] = $now;
$state['arsse_marks']['rows'][11][5] = "New note";
$state['arsse_marks']['rows'][11][4] = $now;
$state['arsse_marks']['rows'][] = [13,5,0,0,$now,'New note'];
$state['arsse_marks']['rows'][] = [13,6,0,0,$now,'New note'];
$state['arsse_marks']['rows'][] = [14,7,0,0,$now,'New note'];
$state['arsse_marks']['rows'][] = [14,8,0,0,$now,'New note'];
$this->compareExpectations($state);
}
public function testMarkATreeFolder() {
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(7));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][] = [13,5,1,0,$now,''];
$state['arsse_marks']['rows'][] = [13,6,1,0,$now,''];
$state['arsse_marks']['rows'][] = [14,7,1,0,$now,''];
$state['arsse_marks']['rows'][] = [14,8,1,0,$now,''];
$this->compareExpectations($state);
}
public function testMarkALeafFolder() {
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(8));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][] = [13,5,1,0,$now,''];
$state['arsse_marks']['rows'][] = [13,6,1,0,$now,''];
$this->compareExpectations($state);
}
public function testMarkAMissingFolder() {
$this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(42));
}
public function testMarkASubscription() {
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->subscription(13));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][] = [13,5,1,0,$now,''];
$state['arsse_marks']['rows'][] = [13,6,1,0,$now,''];
$this->compareExpectations($state);
}
public function testMarkAMissingSubscription() {
$this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(2112));
}
public function testMarkAnArticle() {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->article(20));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][9][3] = 1;
$state['arsse_marks']['rows'][9][4] = $now;
$this->compareExpectations($state);
}
public function testMarkMultipleArticles() {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->articles([2,4,7,20]));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][9][3] = 1;
$state['arsse_marks']['rows'][9][4] = $now;
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
$this->compareExpectations($state);
}
public function testMarkMultipleArticlessUnreadAndStarred() {
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->articles([2,4,7,20]));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][9][2] = 0;
$state['arsse_marks']['rows'][9][3] = 1;
$state['arsse_marks']['rows'][9][4] = $now;
$state['arsse_marks']['rows'][11][2] = 0;
$state['arsse_marks']['rows'][11][4] = $now;
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
$this->compareExpectations($state);
}
public function testMarkTooManyMultipleArticles() {
$this->assertSame(7, Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->articles(range(1, Database::LIMIT_SET_SIZE * 3))));
}
public function testMarkAMissingArticle() {
$this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->article(1));
}
public function testMarkAnEdition() {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->edition(1001));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][9][3] = 1;
$state['arsse_marks']['rows'][9][4] = $now;
$this->compareExpectations($state);
}
public function testMarkMultipleEditions() {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->editions([2,4,7,20]));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][9][3] = 1;
$state['arsse_marks']['rows'][9][4] = $now;
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
$this->compareExpectations($state);
}
public function testMarkMultipleMissingEditions() {
$this->assertSame(0, Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->editions([500,501])));
$state = $this->primeExpectations($this->data, $this->checkTables);
$this->compareExpectations($state);
}
public function testMarkMultipleEditionsUnread() {
Arsse::$db->articleMark($this->user, ['read'=>false], (new Context)->editions([2,4,7,1001]));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][9][2] = 0;
$state['arsse_marks']['rows'][9][4] = $now;
$state['arsse_marks']['rows'][11][2] = 0;
$state['arsse_marks']['rows'][11][4] = $now;
$this->compareExpectations($state);
}
public function testMarkMultipleEditionsUnreadWithStale() {
Arsse::$db->articleMark($this->user, ['read'=>false], (new Context)->editions([2,4,7,20]));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][11][2] = 0;
$state['arsse_marks']['rows'][11][4] = $now;
$this->compareExpectations($state);
}
public function testMarkMultipleEditionsUnreadAndStarredWithStale() {
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->editions([2,4,7,20]));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][9][3] = 1;
$state['arsse_marks']['rows'][9][4] = $now;
$state['arsse_marks']['rows'][11][2] = 0;
$state['arsse_marks']['rows'][11][4] = $now;
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
$this->compareExpectations($state);
}
public function testMarkTooManyMultipleEditions() {
$this->assertSame(7, Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->editions(range(1, 51))));
}
public function testMarkAStaleEditionUnread() {
Arsse::$db->articleMark($this->user, ['read'=>false], (new Context)->edition(20)); // no changes occur
$state = $this->primeExpectations($this->data, $this->checkTables);
$this->compareExpectations($state);
}
public function testMarkAStaleEditionStarred() {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->edition(20));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][9][3] = 1;
$state['arsse_marks']['rows'][9][4] = $now;
$this->compareExpectations($state);
}
public function testMarkAStaleEditionUnreadAndStarred() {
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->edition(20)); // only starred is changed
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][9][3] = 1;
$state['arsse_marks']['rows'][9][4] = $now;
$this->compareExpectations($state);
}
public function testMarkAStaleEditionUnreadAndUnstarred() {
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>false], (new Context)->edition(20)); // no changes occur
$state = $this->primeExpectations($this->data, $this->checkTables);
$this->compareExpectations($state);
}
public function testMarkAMissingEdition() {
$this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->edition(2));
}
public function testMarkByOldestEdition() {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->oldestEdition(19));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][8][3] = 1;
$state['arsse_marks']['rows'][8][4] = $now;
$state['arsse_marks']['rows'][9][3] = 1;
$state['arsse_marks']['rows'][9][4] = $now;
$this->compareExpectations($state);
}
public function testMarkByLatestEdition() {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->latestEdition(20));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][8][3] = 1;
$state['arsse_marks']['rows'][8][4] = $now;
$state['arsse_marks']['rows'][] = [13,5,0,1,$now,''];
$state['arsse_marks']['rows'][] = [13,6,0,1,$now,''];
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
$state['arsse_marks']['rows'][] = [14,8,0,1,$now,''];
$this->compareExpectations($state);
}
public function testMarkByLastMarked() {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->markedSince('2017-01-01T00:00:00Z'));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][8][3] = 1;
$state['arsse_marks']['rows'][8][4] = $now;
$state['arsse_marks']['rows'][9][3] = 1;
$state['arsse_marks']['rows'][9][4] = $now;
$this->compareExpectations($state);
}
public function testMarkByNotLastMarked() {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->notMarkedSince('2000-01-01T00:00:00Z'));
$now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables);
$state['arsse_marks']['rows'][] = [13,5,0,1,$now,''];
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
$this->compareExpectations($state);
}
public function testMarkArticlesWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleMark($this->user, ['read'=>false]);
}
public function testCountArticles() {
$this->assertSame(2, Arsse::$db->articleCount("john.doe@example.com", (new Context)->starred(true)));
$this->assertSame(4, Arsse::$db->articleCount("john.doe@example.com", (new Context)->folder(1)));
$this->assertSame(0, Arsse::$db->articleCount("jane.doe@example.com", (new Context)->starred(true)));
$this->assertSame(10, Arsse::$db->articleCount("john.doe@example.com", (new Context)->articles(range(1, Database::LIMIT_SET_SIZE * 3))));
}
public function testCountArticlesWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleCount($this->user);
}
public function testFetchStarredCounts() {
$exp1 = ['total' => 2, 'unread' => 1, 'read' => 1];
$exp2 = ['total' => 0, 'unread' => 0, 'read' => 0];
$this->assertEquals($exp1, Arsse::$db->articleStarred("john.doe@example.com"));
$this->assertEquals($exp2, Arsse::$db->articleStarred("jane.doe@example.com"));
}
public function testFetchStarredCountsWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleStarred($this->user);
}
public function testFetchLatestEdition() {
$this->assertSame(1001, Arsse::$db->editionLatest($this->user));
$this->assertSame(4, Arsse::$db->editionLatest($this->user, (new Context)->subscription(12)));
}
public function testFetchLatestEditionOfMissingSubscription() {
$this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->editionLatest($this->user, (new Context)->subscription(1));
}
public function testFetchLatestEditionWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->editionLatest($this->user);
}
public function testListTheLabelsOfAnArticle() {
$this->assertEquals([1,2], 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 testListTheLabelsOfAMissingArticle() {
$this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->articleLabelsGet($this->user, 101);
}
public function testListTheLabelsOfAnArticleWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleLabelsGet("john.doe@example.com", 1);
}
public function testListTheCategoriesOfAnArticle() {
$exp = ["Fascinating", "Logical"];
$this->assertSame($exp, Arsse::$db->articleCategoriesGet($this->user, 19));
$exp = ["Interesting", "Logical"];
$this->assertSame($exp, Arsse::$db->articleCategoriesGet($this->user, 20));
$exp = [];
$this->assertSame($exp, Arsse::$db->articleCategoriesGet($this->user, 4));
}
public function testListTheCategoriesOfAMissingArticle() {
$this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->articleCategoriesGet($this->user, 101);
}
public function testListTheCategoriesOfAnArticleWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleCategoriesGet($this->user, 19);
}
/** @dataProvider provideArrayContextOptions */
public function testUseTooFewValuesInArrayContext(string $option) {
$this->assertException("tooShort", "Db", "ExceptionInput");
Arsse::$db->articleList($this->user, (new Context)->annotationTerms([]));
}
public function provideArrayContextOptions() {
foreach([
"articles", "editions",
"subscriptions", "foldersShallow", //"folders",
"tags", "tagNames", "labels", "labelNames",
"searchTerms", "authorTerms", "annotationTerms",
] as $method) {
yield [$method];
}
}
}