mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 21:22:40 +00:00
Convert article and edition ranges to atomic
Unit tests for ranges are still missing
This commit is contained in:
parent
2c2bb4a856
commit
983fa58ec8
11 changed files with 85 additions and 67 deletions
|
@ -1579,7 +1579,16 @@ class Database {
|
||||||
continue;
|
continue;
|
||||||
} elseif ($op === "between") {
|
} elseif ($op === "between") {
|
||||||
// option is a range
|
// option is a range
|
||||||
$q->setWhereNot("{$colDefs[$col]} BETWEEN ? AND ?", [$type, $type], $context->$m);
|
if ($context->$m[0] === null) {
|
||||||
|
// range is open at the low end
|
||||||
|
$q->setWhere("{$colDefs[$col]} <= ?", $type, $context->$m[1]);
|
||||||
|
} elseif ($context->$m[1] === null) {
|
||||||
|
// range is open at the high end
|
||||||
|
$q->setWhere("{$colDefs[$col]} >= ?", $type, $context->$m[0]);
|
||||||
|
} else {
|
||||||
|
// range is bounded in both directions
|
||||||
|
$q->setWhere("{$colDefs[$col]} BETWEEN ? AND ?", [$type, $type], $context->$m);
|
||||||
|
}
|
||||||
} elseif (is_array($context->$m)) {
|
} elseif (is_array($context->$m)) {
|
||||||
// context option is an array of values
|
// context option is an array of values
|
||||||
if (!$context->$m) {
|
if (!$context->$m) {
|
||||||
|
@ -1598,7 +1607,16 @@ class Database {
|
||||||
continue;
|
continue;
|
||||||
} elseif ($op === "between") {
|
} elseif ($op === "between") {
|
||||||
// option is a range
|
// option is a range
|
||||||
$q->setWhereNot("{$colDefs[$col]} BETWEEN ? AND ?", [$type, $type], $context->not->$m);
|
if ($context->not->$m[0] === null) {
|
||||||
|
// range is open at the low end
|
||||||
|
$q->setWhereNot("{$colDefs[$col]} <= ?", $type, $context->not->$m[1]);
|
||||||
|
} elseif ($context->not->$m[1] === null) {
|
||||||
|
// range is open at the high end
|
||||||
|
$q->setWhereNot("{$colDefs[$col]} >= ?", $type, $context->not->$m[0]);
|
||||||
|
} else {
|
||||||
|
// range is bounded in both directions
|
||||||
|
$q->setWhereNot("{$colDefs[$col]} BETWEEN ? AND ?", [$type, $type], $context->not->$m);
|
||||||
|
}
|
||||||
} elseif (is_array($context->not->$m)) {
|
} elseif (is_array($context->not->$m)) {
|
||||||
if (!$context->not->$m) {
|
if (!$context->not->$m) {
|
||||||
// for exclusions we don't care if the array is empty
|
// for exclusions we don't care if the array is empty
|
||||||
|
|
|
@ -388,10 +388,10 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
if ($G['with_ids']) {
|
if ($G['with_ids']) {
|
||||||
$c->articles(explode(",", $G['with_ids']))->hidden(null);
|
$c->articles(explode(",", $G['with_ids']))->hidden(null);
|
||||||
} elseif ($G['max_id']) {
|
} elseif ($G['max_id']) {
|
||||||
$c->latestArticle($G['max_id'] - 1);
|
$c->articleRange(null, $G['max_id'] - 1);
|
||||||
$reverse = true;
|
$reverse = true;
|
||||||
} elseif ($G['since_id']) {
|
} elseif ($G['since_id']) {
|
||||||
$c->oldestArticle($G['since_id'] + 1);
|
$c->articleRange($G['since_id'] + 1, null);
|
||||||
}
|
}
|
||||||
// handle the undocumented options
|
// handle the undocumented options
|
||||||
if ($G['group_ids']) {
|
if ($G['group_ids']) {
|
||||||
|
|
|
@ -894,8 +894,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
->offset($query['offset'])
|
->offset($query['offset'])
|
||||||
->starred($query['starred'])
|
->starred($query['starred'])
|
||||||
->modifiedRange($query['after'], $query['before']) // FIXME: This may not be the correct date field
|
->modifiedRange($query['after'], $query['before']) // FIXME: This may not be the correct date field
|
||||||
->oldestArticle($query['after_entry_id'] ? $query['after_entry_id'] + 1 : null) // FIXME: This might be edition
|
->articleRange($query['after_entry_id'] ? $query['after_entry_id'] + 1 : null, $query['before_entry_id'] ? $query['before_entry_id'] - 1 : null) // FIXME: This might be edition
|
||||||
->latestArticle($query['before_entry_id'] ? $query['before_entry_id'] - 1 : null)
|
|
||||||
->searchTerms(strlen($query['search'] ?? "") ? preg_split("/\s+/", $query['search']) : null); // NOTE: Miniflux matches only whole words; we match simple substrings
|
->searchTerms(strlen($query['search'] ?? "") ? preg_split("/\s+/", $query['search']) : null); // NOTE: Miniflux matches only whole words; we match simple substrings
|
||||||
if ($query['category_id']) {
|
if ($query['category_id']) {
|
||||||
if ($query['category_id'] === 1) {
|
if ($query['category_id'] === 1) {
|
||||||
|
|
|
@ -346,7 +346,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
}
|
}
|
||||||
// build the context
|
// build the context
|
||||||
$c = (new Context)->hidden(false);
|
$c = (new Context)->hidden(false);
|
||||||
$c->latestEdition((int) $data['newestItemId']);
|
$c->editionRange(null, (int) $data['newestItemId']);
|
||||||
$c->folder((int) $url[1]);
|
$c->folder((int) $url[1]);
|
||||||
// perform the operation
|
// perform the operation
|
||||||
try {
|
try {
|
||||||
|
@ -501,7 +501,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
}
|
}
|
||||||
// build the context
|
// build the context
|
||||||
$c = (new Context)->hidden(false);
|
$c = (new Context)->hidden(false);
|
||||||
$c->latestEdition((int) $data['newestItemId']);
|
$c->editionRange(null, (int) $data['newestItemId']);
|
||||||
$c->subscription((int) $url[1]);
|
$c->subscription((int) $url[1]);
|
||||||
// perform the operation
|
// perform the operation
|
||||||
try {
|
try {
|
||||||
|
@ -526,9 +526,9 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
// set the edition mark-off; the database uses an or-equal comparison for internal consistency, but the protocol does not, so we must adjust by one
|
// set the edition mark-off; the database uses an or-equal comparison for internal consistency, but the protocol does not, so we must adjust by one
|
||||||
if ($data['offset'] > 0) {
|
if ($data['offset'] > 0) {
|
||||||
if ($reverse) {
|
if ($reverse) {
|
||||||
$c->latestEdition($data['offset'] - 1);
|
$c->editionRange(null, $data['offset'] - 1);
|
||||||
} else {
|
} else {
|
||||||
$c->oldestEdition($data['offset'] + 1);
|
$c->editionRange($data['offset'] + 1, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// set whether to only return unread
|
// set whether to only return unread
|
||||||
|
@ -597,7 +597,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
}
|
}
|
||||||
// build the context
|
// build the context
|
||||||
$c = (new Context)->hidden(false);
|
$c = (new Context)->hidden(false);
|
||||||
$c->latestEdition((int) $data['newestItemId']);
|
$c->editionRange(null, (int) $data['newestItemId']);
|
||||||
// perform the operation
|
// perform the operation
|
||||||
Arsse::$db->articleMark(Arsse::$user->id, ['read' => true], $c);
|
Arsse::$db->articleMark(Arsse::$user->id, ['read' => true], $c);
|
||||||
return new EmptyResponse(204);
|
return new EmptyResponse(204);
|
||||||
|
|
|
@ -1550,7 +1550,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
}
|
}
|
||||||
// set the minimum article ID
|
// set the minimum article ID
|
||||||
if ($data['since_id'] > 0) {
|
if ($data['since_id'] > 0) {
|
||||||
$c->oldestArticle($data['since_id'] + 1);
|
$c->articleRange($data['since_id'] + 1, null);
|
||||||
}
|
}
|
||||||
// return results
|
// return results
|
||||||
return Arsse::$db->articleList(Arsse::$user->id, $c, $fields, $order);
|
return Arsse::$db->articleList(Arsse::$user->id, $c, $fields, $order);
|
||||||
|
|
|
@ -456,12 +456,12 @@ trait SeriesArticle {
|
||||||
'Not hidden' => [(new Context)->hidden(false), [1,2,3,4,5,7,8,19,20]],
|
'Not hidden' => [(new Context)->hidden(false), [1,2,3,4,5,7,8,19,20]],
|
||||||
'Labelled' => [(new Context)->labelled(true), [1,5,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 labelled' => [(new Context)->labelled(false), [2,3,4,6,7]],
|
||||||
'Not after edition 999' => [(new Context)->subscription(5)->latestEdition(999), [19]],
|
'Not after edition 999' => [(new Context)->subscription(5)->editionRange(null, 999), [19]],
|
||||||
'Not after edition 19' => [(new Context)->subscription(5)->latestEdition(19), [19]],
|
'Not after edition 19' => [(new Context)->subscription(5)->editionRange(null, 19), [19]],
|
||||||
'Not before edition 999' => [(new Context)->subscription(5)->oldestEdition(999), [20]],
|
'Not before edition 999' => [(new Context)->subscription(5)->editionRange(999, null), [20]],
|
||||||
'Not before edition 1001' => [(new Context)->subscription(5)->oldestEdition(1001), [20]],
|
'Not before edition 1001' => [(new Context)->subscription(5)->editionRange(1001, null), [20]],
|
||||||
'Not after article 3' => [(new Context)->latestArticle(3), [1,2,3]],
|
'Not after article 3' => [(new Context)->articleRange(null, 3), [1,2,3]],
|
||||||
'Not before article 19' => [(new Context)->oldestArticle(19), [19,20]],
|
'Not before article 19' => [(new Context)->articleRange(19, null), [19,20]],
|
||||||
'Modified by author since 2005' => [(new Context)->modifiedRange("2005-01-01T00:00:00Z", null), [2,4,6,8,20]],
|
'Modified by author since 2005' => [(new Context)->modifiedRange("2005-01-01T00:00:00Z", null), [2,4,6,8,20]],
|
||||||
'Modified by author since 2010' => [(new Context)->modifiedRange("2010-01-01T00:00:00Z", null), [2,4,6,8,20]],
|
'Modified by author since 2010' => [(new Context)->modifiedRange("2010-01-01T00:00:00Z", null), [2,4,6,8,20]],
|
||||||
'Not modified by author since 2005' => [(new Context)->modifiedRange(null, "2005-01-01T00:00:00Z"), [1,3,5,7,19]],
|
'Not modified by author since 2005' => [(new Context)->modifiedRange(null, "2005-01-01T00:00:00Z"), [1,3,5,7,19]],
|
||||||
|
@ -472,7 +472,7 @@ trait SeriesArticle {
|
||||||
'Not marked or labelled since 2005' => [(new Context)->markedRange(null, "2005-01-01T00:00:00Z"), [1,3,5,7]],
|
'Not marked or labelled since 2005' => [(new Context)->markedRange(null, "2005-01-01T00:00:00Z"), [1,3,5,7]],
|
||||||
'Marked or labelled between 2000 and 2015' => [(new Context)->markedRange("2000-01-01T00:00:00Z", "2015-12-31T23:59:59Z"), [1,2,3,4,5,6,7,8,20]],
|
'Marked or labelled between 2000 and 2015' => [(new Context)->markedRange("2000-01-01T00:00:00Z", "2015-12-31T23:59:59Z"), [1,2,3,4,5,6,7,8,20]],
|
||||||
'Marked or labelled in 2010' => [(new Context)->markedRange("2010-01-01T00:00:00Z", "2010-12-31T23:59:59Z"), [2,4,6,20]],
|
'Marked or labelled in 2010' => [(new Context)->markedRange("2010-01-01T00:00:00Z", "2010-12-31T23:59:59Z"), [2,4,6,20]],
|
||||||
'Paged results' => [(new Context)->limit(2)->oldestEdition(4), [4,5]],
|
'Paged results' => [(new Context)->limit(2)->editionRange(4, null), [4,5]],
|
||||||
'With label ID 1' => [(new Context)->label(1), [1,19]],
|
'With label ID 1' => [(new Context)->label(1), [1,19]],
|
||||||
'With label ID 2' => [(new Context)->label(2), [1,5,20]],
|
'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 ID 1 or 2' => [(new Context)->labels([1,2]), [1,5,19,20]],
|
||||||
|
@ -929,7 +929,7 @@ trait SeriesArticle {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMarkByOldestEdition(): void {
|
public function testMarkByOldestEdition(): void {
|
||||||
Arsse::$db->articleMark($this->user, ['starred' => true], (new Context)->oldestEdition(19));
|
Arsse::$db->articleMark($this->user, ['starred' => true], (new Context)->editionRange(19, null));
|
||||||
$now = Date::transform(time(), "sql");
|
$now = Date::transform(time(), "sql");
|
||||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||||
$state['arsse_marks']['rows'][8][3] = 1;
|
$state['arsse_marks']['rows'][8][3] = 1;
|
||||||
|
@ -940,7 +940,7 @@ trait SeriesArticle {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMarkByLatestEdition(): void {
|
public function testMarkByLatestEdition(): void {
|
||||||
Arsse::$db->articleMark($this->user, ['starred' => true], (new Context)->latestEdition(20));
|
Arsse::$db->articleMark($this->user, ['starred' => true], (new Context)->editionRange(null, 20));
|
||||||
$now = Date::transform(time(), "sql");
|
$now = Date::transform(time(), "sql");
|
||||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||||
$state['arsse_marks']['rows'][8][3] = 1;
|
$state['arsse_marks']['rows'][8][3] = 1;
|
||||||
|
|
|
@ -11,6 +11,8 @@ use JKingWeb\Arsse\Misc\ValueInfo;
|
||||||
|
|
||||||
/** @covers \JKingWeb\Arsse\Context\Context<extended> */
|
/** @covers \JKingWeb\Arsse\Context\Context<extended> */
|
||||||
class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
|
protected $ranges = ['modifiedRange', 'markedRange', 'articleRange', 'editionRange'];
|
||||||
|
|
||||||
public function testVerifyInitialState(): void {
|
public function testVerifyInitialState(): void {
|
||||||
$c = new Context;
|
$c = new Context;
|
||||||
foreach ((new \ReflectionObject($c))->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) {
|
foreach ((new \ReflectionObject($c))->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) {
|
||||||
|
@ -19,7 +21,11 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
}
|
}
|
||||||
$method = $m->name;
|
$method = $m->name;
|
||||||
$this->assertFalse($c->$method(), "Context method $method did not initially return false");
|
$this->assertFalse($c->$method(), "Context method $method did not initially return false");
|
||||||
$this->assertEquals(null, $c->$method, "Context property $method is not initially falsy");
|
if (in_array($method, $this->ranges)) {
|
||||||
|
$this->assertEquals([null, null], $c->$method, "Context property $method is not initially a two-member falsy array");
|
||||||
|
} else {
|
||||||
|
$this->assertEquals(null, $c->$method, "Context property $method is not initially falsy");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,10 +46,6 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
'subscriptions' => [44, 2112],
|
'subscriptions' => [44, 2112],
|
||||||
'article' => 255,
|
'article' => 255,
|
||||||
'edition' => 65535,
|
'edition' => 65535,
|
||||||
'latestArticle' => 47,
|
|
||||||
'oldestArticle' => 1337,
|
|
||||||
'latestEdition' => 47,
|
|
||||||
'oldestEdition' => 1337,
|
|
||||||
'unread' => true,
|
'unread' => true,
|
||||||
'starred' => true,
|
'starred' => true,
|
||||||
'hidden' => true,
|
'hidden' => true,
|
||||||
|
@ -61,10 +63,9 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
'authorTerms' => ["foo", "bar"],
|
'authorTerms' => ["foo", "bar"],
|
||||||
'not' => (new Context)->subscription(5),
|
'not' => (new Context)->subscription(5),
|
||||||
];
|
];
|
||||||
$ranges = ['modifiedRange', 'markedRange', 'articleRange', 'editionRange'];
|
|
||||||
$c = new Context;
|
$c = new Context;
|
||||||
foreach ((new \ReflectionObject($c))->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) {
|
foreach ((new \ReflectionObject($c))->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) {
|
||||||
if ($m->isStatic() || strpos($m->name, "__") === 0 || in_array($m->name, $ranges)) {
|
if ($m->isStatic() || strpos($m->name, "__") === 0 || in_array($m->name, $this->ranges)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$method = $m->name;
|
$method = $m->name;
|
||||||
|
|
|
@ -316,12 +316,12 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
["items&group_ids=1,2,3,4", (clone $c)->tags([1,2,3,4])->hidden(false), false],
|
["items&group_ids=1,2,3,4", (clone $c)->tags([1,2,3,4])->hidden(false), false],
|
||||||
["items&feed_ids=1,2,3,4", (clone $c)->subscriptions([1,2,3,4])->hidden(false), false],
|
["items&feed_ids=1,2,3,4", (clone $c)->subscriptions([1,2,3,4])->hidden(false), false],
|
||||||
["items&with_ids=1,2,3,4", (clone $c)->articles([1,2,3,4]), false],
|
["items&with_ids=1,2,3,4", (clone $c)->articles([1,2,3,4]), false],
|
||||||
["items&since_id=1", (clone $c)->oldestArticle(2)->hidden(false), false],
|
["items&since_id=1", (clone $c)->articleRange(2, null)->hidden(false), false],
|
||||||
["items&max_id=2", (clone $c)->latestArticle(1)->hidden(false), true],
|
["items&max_id=2", (clone $c)->articleRange(null, 1)->hidden(false), true],
|
||||||
["items&with_ids=1,2,3,4&max_id=6", (clone $c)->articles([1,2,3,4]), false],
|
["items&with_ids=1,2,3,4&max_id=6", (clone $c)->articles([1,2,3,4]), false],
|
||||||
["items&with_ids=1,2,3,4&since_id=6", (clone $c)->articles([1,2,3,4]), false],
|
["items&with_ids=1,2,3,4&since_id=6", (clone $c)->articles([1,2,3,4]), false],
|
||||||
["items&max_id=3&since_id=6", (clone $c)->latestArticle(2)->hidden(false), true],
|
["items&max_id=3&since_id=6", (clone $c)->articleRange(null, 2)->hidden(false), true],
|
||||||
["items&feed_ids=1,2,3,4&since_id=6", (clone $c)->subscriptions([1,2,3,4])->oldestArticle(7)->hidden(false), false],
|
["items&feed_ids=1,2,3,4&since_id=6", (clone $c)->subscriptions([1,2,3,4])->articleRange(7, null)->hidden(false), false],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -772,8 +772,8 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
["/entries?before=0", $c, $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
["/entries?before=0", $c, $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||||
["/entries?before=1", (clone $c)->modifiedRange(null, 1), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
["/entries?before=1", (clone $c)->modifiedRange(null, 1), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||||
["/entries?before=1&after=0", (clone $c)->modifiedRange(0, 1), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
["/entries?before=1&after=0", (clone $c)->modifiedRange(0, 1), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||||
["/entries?after_entry_id=42", (clone $c)->oldestArticle(43), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
["/entries?after_entry_id=42", (clone $c)->articleRange(43, null), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||||
["/entries?before_entry_id=47", (clone $c)->latestArticle(46), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
["/entries?before_entry_id=47", (clone $c)->articleRange(null, 46), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||||
["/entries?search=alpha%20beta", (clone $c)->searchTerms(["alpha", "beta"]), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
["/entries?search=alpha%20beta", (clone $c)->searchTerms(["alpha", "beta"]), $o, self::ENTRIES, false, new Response(['total' => sizeof(self::ENTRIES_OUT), 'entries' => self::ENTRIES_OUT])],
|
||||||
["/entries?limit=4", (clone $c)->limit(4), $o, self::ENTRIES, true, new Response(['total' => 2112, 'entries' => self::ENTRIES_OUT])],
|
["/entries?limit=4", (clone $c)->limit(4), $o, self::ENTRIES, true, new Response(['total' => 2112, 'entries' => self::ENTRIES_OUT])],
|
||||||
["/entries?offset=20", (clone $c)->offset(20), $o, [], true, new Response(['total' => 2112, 'entries' => []])],
|
["/entries?offset=20", (clone $c)->offset(20), $o, [], true, new Response(['total' => 2112, 'entries' => []])],
|
||||||
|
|
|
@ -686,40 +686,40 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
$r200 = new Response(['items' => $this->articles['rest']]);
|
$r200 = new Response(['items' => $this->articles['rest']]);
|
||||||
$r422 = new EmptyResponse(422);
|
$r422 = new EmptyResponse(422);
|
||||||
return [
|
return [
|
||||||
["/items", [], clone $c, $out, $r200],
|
["/items", [], clone $c, $out, $r200],
|
||||||
["/items", ['type' => 0, 'id' => 42], (clone $c)->subscription(42), new ExceptionInput("idMissing"), $r422],
|
["/items", ['type' => 0, 'id' => 42], (clone $c)->subscription(42), new ExceptionInput("idMissing"), $r422],
|
||||||
["/items", ['type' => 1, 'id' => 2112], (clone $c)->folder(2112), new ExceptionInput("idMissing"), $r422],
|
["/items", ['type' => 1, 'id' => 2112], (clone $c)->folder(2112), new ExceptionInput("idMissing"), $r422],
|
||||||
["/items", ['type' => 0, 'id' => -1], (clone $c)->subscription(-1), new ExceptionInput("typeViolation"), $r422],
|
["/items", ['type' => 0, 'id' => -1], (clone $c)->subscription(-1), new ExceptionInput("typeViolation"), $r422],
|
||||||
["/items", ['type' => 1, 'id' => -1], (clone $c)->folder(-1), new ExceptionInput("typeViolation"), $r422],
|
["/items", ['type' => 1, 'id' => -1], (clone $c)->folder(-1), new ExceptionInput("typeViolation"), $r422],
|
||||||
["/items", ['type' => 2, 'id' => 0], (clone $c)->starred(true), $out, $r200],
|
["/items", ['type' => 2, 'id' => 0], (clone $c)->starred(true), $out, $r200],
|
||||||
["/items", ['type' => 3, 'id' => 0], clone $c, $out, $r200],
|
["/items", ['type' => 3, 'id' => 0], clone $c, $out, $r200],
|
||||||
["/items", ['getRead' => true], clone $c, $out, $r200],
|
["/items", ['getRead' => true], clone $c, $out, $r200],
|
||||||
["/items", ['getRead' => false], (clone $c)->unread(true), $out, $r200],
|
["/items", ['getRead' => false], (clone $c)->unread(true), $out, $r200],
|
||||||
["/items", ['lastModified' => $t->getTimestamp()], (clone $c)->markedRange($t, null), $out, $r200],
|
["/items", ['lastModified' => $t->getTimestamp()], (clone $c)->markedRange($t, null), $out, $r200],
|
||||||
["/items", ['oldestFirst' => true, 'batchSize' => 10, 'offset' => 5], (clone $c)->oldestEdition(6)->limit(10), $out, $r200],
|
["/items", ['oldestFirst' => true, 'batchSize' => 10, 'offset' => 5], (clone $c)->editionRange(6, null)->limit(10), $out, $r200],
|
||||||
["/items", ['oldestFirst' => false, 'batchSize' => 5, 'offset' => 5], (clone $c)->latestEdition(4)->limit(5), $out, $r200],
|
["/items", ['oldestFirst' => false, 'batchSize' => 5, 'offset' => 5], (clone $c)->editionRange(null, 4)->limit(5), $out, $r200],
|
||||||
["/items", ['oldestFirst' => false, 'batchSize' => 5, 'offset' => 0], (clone $c)->limit(5), $out, $r200],
|
["/items", ['oldestFirst' => false, 'batchSize' => 5, 'offset' => 0], (clone $c)->limit(5), $out, $r200],
|
||||||
["/items/updated", [], clone $c, $out, $r200],
|
["/items/updated", [], clone $c, $out, $r200],
|
||||||
["/items/updated", ['type' => 0, 'id' => 42], (clone $c)->subscription(42), new ExceptionInput("idMissing"), $r422],
|
["/items/updated", ['type' => 0, 'id' => 42], (clone $c)->subscription(42), new ExceptionInput("idMissing"), $r422],
|
||||||
["/items/updated", ['type' => 1, 'id' => 2112], (clone $c)->folder(2112), new ExceptionInput("idMissing"), $r422],
|
["/items/updated", ['type' => 1, 'id' => 2112], (clone $c)->folder(2112), new ExceptionInput("idMissing"), $r422],
|
||||||
["/items/updated", ['type' => 0, 'id' => -1], (clone $c)->subscription(-1), new ExceptionInput("typeViolation"), $r422],
|
["/items/updated", ['type' => 0, 'id' => -1], (clone $c)->subscription(-1), new ExceptionInput("typeViolation"), $r422],
|
||||||
["/items/updated", ['type' => 1, 'id' => -1], (clone $c)->folder(-1), new ExceptionInput("typeViolation"), $r422],
|
["/items/updated", ['type' => 1, 'id' => -1], (clone $c)->folder(-1), new ExceptionInput("typeViolation"), $r422],
|
||||||
["/items/updated", ['type' => 2, 'id' => 0], (clone $c)->starred(true), $out, $r200],
|
["/items/updated", ['type' => 2, 'id' => 0], (clone $c)->starred(true), $out, $r200],
|
||||||
["/items/updated", ['type' => 3, 'id' => 0], clone $c, $out, $r200],
|
["/items/updated", ['type' => 3, 'id' => 0], clone $c, $out, $r200],
|
||||||
["/items/updated", ['getRead' => true], clone $c, $out, $r200],
|
["/items/updated", ['getRead' => true], clone $c, $out, $r200],
|
||||||
["/items/updated", ['getRead' => false], (clone $c)->unread(true), $out, $r200],
|
["/items/updated", ['getRead' => false], (clone $c)->unread(true), $out, $r200],
|
||||||
["/items/updated", ['lastModified' => $t->getTimestamp()], (clone $c)->markedRange($t, null), $out, $r200],
|
["/items/updated", ['lastModified' => $t->getTimestamp()], (clone $c)->markedRange($t, null), $out, $r200],
|
||||||
["/items/updated", ['oldestFirst' => true, 'batchSize' => 10, 'offset' => 5], (clone $c)->oldestEdition(6)->limit(10), $out, $r200],
|
["/items/updated", ['oldestFirst' => true, 'batchSize' => 10, 'offset' => 5], (clone $c)->editionRange(6, null)->limit(10), $out, $r200],
|
||||||
["/items/updated", ['oldestFirst' => false, 'batchSize' => 5, 'offset' => 5], (clone $c)->latestEdition(4)->limit(5), $out, $r200],
|
["/items/updated", ['oldestFirst' => false, 'batchSize' => 5, 'offset' => 5], (clone $c)->editionRange(null, 4)->limit(5), $out, $r200],
|
||||||
["/items/updated", ['oldestFirst' => false, 'batchSize' => 5, 'offset' => 0], (clone $c)->limit(5), $out, $r200],
|
["/items/updated", ['oldestFirst' => false, 'batchSize' => 5, 'offset' => 0], (clone $c)->limit(5), $out, $r200],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMarkAFolderRead(): void {
|
public function testMarkAFolderRead(): void {
|
||||||
$read = ['read' => true];
|
$read = ['read' => true];
|
||||||
$in = json_encode(['newestItemId' => 2112]);
|
$in = json_encode(['newestItemId' => 2112]);
|
||||||
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->folder(1)->latestEdition(2112)->hidden(false)))->returns(42);
|
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->folder(1)->editionRange(null, 2112)->hidden(false)))->returns(42);
|
||||||
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->folder(42)->latestEdition(2112)->hidden(false)))->throws(new ExceptionInput("idMissing")); // folder doesn't exist
|
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->folder(42)->editionRange(null, 2112)->hidden(false)))->throws(new ExceptionInput("idMissing")); // folder doesn't exist
|
||||||
$exp = new EmptyResponse(204);
|
$exp = new EmptyResponse(204);
|
||||||
$this->assertMessage($exp, $this->req("PUT", "/folders/1/read", $in));
|
$this->assertMessage($exp, $this->req("PUT", "/folders/1/read", $in));
|
||||||
$this->assertMessage($exp, $this->req("PUT", "/folders/1/read?newestItemId=2112"));
|
$this->assertMessage($exp, $this->req("PUT", "/folders/1/read?newestItemId=2112"));
|
||||||
|
@ -733,8 +733,8 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
public function testMarkASubscriptionRead(): void {
|
public function testMarkASubscriptionRead(): void {
|
||||||
$read = ['read' => true];
|
$read = ['read' => true];
|
||||||
$in = json_encode(['newestItemId' => 2112]);
|
$in = json_encode(['newestItemId' => 2112]);
|
||||||
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->subscription(1)->latestEdition(2112)->hidden(false)))->returns(42);
|
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->subscription(1)->editionRange(null, 2112)->hidden(false)))->returns(42);
|
||||||
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->subscription(42)->latestEdition(2112)->hidden(false)))->throws(new ExceptionInput("idMissing")); // subscription doesn't exist
|
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->subscription(42)->editionRange(null, 2112)->hidden(false)))->throws(new ExceptionInput("idMissing")); // subscription doesn't exist
|
||||||
$exp = new EmptyResponse(204);
|
$exp = new EmptyResponse(204);
|
||||||
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/read", $in));
|
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/read", $in));
|
||||||
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/read?newestItemId=2112"));
|
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/read?newestItemId=2112"));
|
||||||
|
@ -748,7 +748,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
public function testMarkAllItemsRead(): void {
|
public function testMarkAllItemsRead(): void {
|
||||||
$read = ['read' => true];
|
$read = ['read' => true];
|
||||||
$in = json_encode(['newestItemId' => 2112]);
|
$in = json_encode(['newestItemId' => 2112]);
|
||||||
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->latestEdition(2112)))->returns(42);
|
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->editionRange(null, 2112)))->returns(42);
|
||||||
$exp = new EmptyResponse(204);
|
$exp = new EmptyResponse(204);
|
||||||
$this->assertMessage($exp, $this->req("PUT", "/items/read", $in));
|
$this->assertMessage($exp, $this->req("PUT", "/items/read", $in));
|
||||||
$this->assertMessage($exp, $this->req("PUT", "/items/read?newestItemId=2112"));
|
$this->assertMessage($exp, $this->req("PUT", "/items/read?newestItemId=2112"));
|
||||||
|
|
|
@ -1539,7 +1539,7 @@ LONG_STRING;
|
||||||
[true, ['feed_id' => -4, 'limit' => 5], $out, (clone $c)->limit(5), $fields, $sort, $expFull],
|
[true, ['feed_id' => -4, 'limit' => 5], $out, (clone $c)->limit(5), $fields, $sort, $expFull],
|
||||||
[true, ['feed_id' => -4, 'skip' => 2], $out, (clone $c)->offset(2), $fields, $sort, $expFull],
|
[true, ['feed_id' => -4, 'skip' => 2], $out, (clone $c)->offset(2), $fields, $sort, $expFull],
|
||||||
[true, ['feed_id' => -4, 'limit' => 5, 'skip' => 2], $out, (clone $c)->limit(5)->offset(2), $fields, $sort, $expFull],
|
[true, ['feed_id' => -4, 'limit' => 5, 'skip' => 2], $out, (clone $c)->limit(5)->offset(2), $fields, $sort, $expFull],
|
||||||
[true, ['feed_id' => -4, 'since_id' => 47], $out, (clone $c)->oldestArticle(48), $fields, $sort, $expFull],
|
[true, ['feed_id' => -4, 'since_id' => 47], $out, (clone $c)->articleRange(48, null), $fields, $sort, $expFull],
|
||||||
[true, ['feed_id' => -3, 'is_cat' => true], $out, $c, $fields, $sort, $expFull],
|
[true, ['feed_id' => -3, 'is_cat' => true], $out, $c, $fields, $sort, $expFull],
|
||||||
[true, ['feed_id' => -4, 'is_cat' => true], $out, $c, $fields, $sort, $expFull],
|
[true, ['feed_id' => -4, 'is_cat' => true], $out, $c, $fields, $sort, $expFull],
|
||||||
[true, ['feed_id' => -2, 'is_cat' => true], $out, (clone $c)->labelled(true), $fields, $sort, $expFull],
|
[true, ['feed_id' => -2, 'is_cat' => true], $out, (clone $c)->labelled(true), $fields, $sort, $expFull],
|
||||||
|
@ -1571,7 +1571,7 @@ LONG_STRING;
|
||||||
[false, ['feed_id' => -4, 'limit' => 5], $comp, (clone $c)->limit(5), ["id"], $sort, $expComp],
|
[false, ['feed_id' => -4, 'limit' => 5], $comp, (clone $c)->limit(5), ["id"], $sort, $expComp],
|
||||||
[false, ['feed_id' => -4, 'skip' => 2], $comp, (clone $c)->limit(null)->offset(2), ["id"], $sort, $expComp],
|
[false, ['feed_id' => -4, 'skip' => 2], $comp, (clone $c)->limit(null)->offset(2), ["id"], $sort, $expComp],
|
||||||
[false, ['feed_id' => -4, 'limit' => 5, 'skip' => 2], $comp, (clone $c)->limit(5)->offset(2), ["id"], $sort, $expComp],
|
[false, ['feed_id' => -4, 'limit' => 5, 'skip' => 2], $comp, (clone $c)->limit(5)->offset(2), ["id"], $sort, $expComp],
|
||||||
[false, ['feed_id' => -4, 'since_id' => 47], $comp, (clone $c)->limit(null)->oldestArticle(48), ["id"], $sort, $expComp],
|
[false, ['feed_id' => -4, 'since_id' => 47], $comp, (clone $c)->limit(null)->articleRange(48, null), ["id"], $sort, $expComp],
|
||||||
[false, ['feed_id' => -6], $comp, (clone $c)->limit(null)->unread(false)->markedRange(Date::sub("PT24H", $t), null), ["id"], ["marked_date desc"], $expComp],
|
[false, ['feed_id' => -6], $comp, (clone $c)->limit(null)->unread(false)->markedRange(Date::sub("PT24H", $t), null), ["id"], ["marked_date desc"], $expComp],
|
||||||
[false, ['feed_id' => -6, 'view_mode' => "unread"], null, (clone $c)->limit(null), ["id"], $sort, $this->respGood([])],
|
[false, ['feed_id' => -6, 'view_mode' => "unread"], null, (clone $c)->limit(null), ["id"], $sort, $this->respGood([])],
|
||||||
[false, ['feed_id' => -3], $comp, (clone $c)->limit(null)->unread(true)->modifiedRange(Date::sub("PT24H", $t), null), ["id"], $sort, $expComp],
|
[false, ['feed_id' => -3], $comp, (clone $c)->limit(null)->unread(true)->modifiedRange(Date::sub("PT24H", $t), null), ["id"], $sort, $expComp],
|
||||||
|
|
Loading…
Reference in a new issue