Browse Source

Progress on TT-RSS tests

rpm
J. King 3 years ago
parent
commit
9dfe3919cf
  1. 283
      tests/cases/REST/TinyTinyRSS/TestAPI.php

283
tests/cases/REST/TinyTinyRSS/TestAPI.php

@ -699,7 +699,7 @@ LONG_STRING;
];
}
/** @dataProvider provideSubscriptionAdditions */
/** @dataProvider provideFeedSubscriptions */
public function testAddASubscription(array $in, ?array $data, $out, ResponseInterface $exp): void {
$in = array_merge(['op' => "subscribeToFeed", 'sid' => "PriestsOfSyrinx"], $in);
$action = ($out instanceof \Exception) ? "throws" : "returns";
@ -725,7 +725,7 @@ LONG_STRING;
$this->dbMock->subscriptionPropertiesSet->never()->calledWith($this->userId, 4, ['folder' => 1]);
}
public function provideSubscriptionAdditions(): iterable {
public function provideFeedSubscriptions(): iterable {
return [
[['feed_url' => "http://example.com/0"], [$this->userId, "http://example.com/0", "", ""], 2, $this->respGood(['code' => 1, 'feed_id' => 2])],
[['feed_url' => "http://example.com/1", 'category_id' => 42], [$this->userId, "http://example.com/1", "", ""], new FeedException("unauthorized"), $this->respGood(['code' => 5, 'message' => (new FeedException("unauthorized"))->getMessage()])],
@ -744,110 +744,80 @@ LONG_STRING;
];
}
public function testRemoveASubscription(): void {
$in = [
['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42],
['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112],
['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => -1],
['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx"],
];
\Phake::when(Arsse::$db)->subscriptionRemove(Arsse::$user->id, $this->anything())->thenThrow(new ExceptionInput("typeViolation"));
\Phake::when(Arsse::$db)->subscriptionRemove(Arsse::$user->id, 2112)->thenThrow(new ExceptionInput("subjectMissing"));
\Phake::when(Arsse::$db)->subscriptionRemove(Arsse::$user->id, 42)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing"));
// succefully delete a folder
$exp = $this->respGood(['status' => "OK"]);
$this->assertMessage($exp, $this->req($in[0]));
// try deleting it again (this should noisily fail, as should everything else)
$exp = $this->respErr("FEED_NOT_FOUND");
$this->assertMessage($exp, $this->req($in[0]));
$this->assertMessage($exp, $this->req($in[1]));
$this->assertMessage($exp, $this->req($in[2]));
$this->assertMessage($exp, $this->req($in[3]));
\Phake::verify(Arsse::$db, \Phake::times(5))->subscriptionRemove(Arsse::$user->id, $this->anything());
/** @dataProvider provideFeedUnsubscriptions */
public function testRemoveASubscription(array $in, ?array $data, $out, ResponseInterface $exp): void {
$in = array_merge(['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx"], $in);
$action = ($out instanceof \Exception) ? "throws" : "returns";
$this->dbMock->subscriptionRemove->$action($out);
$this->assertMessage($exp, $this->req($in));
if ($out !== null) {
$this->dbMock->subscriptionRemove->calledWith(...$data);
} else {
$this->dbMock->subscriptionRemove->never()->called();
}
}
public function testMoveASubscription(): void {
$in = [
['op' => "moveFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'category_id' => 1],
['op' => "moveFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112, 'category_id' => 2],
['op' => "moveFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'category_id' => 0],
['op' => "moveFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'category_id' => 47],
['op' => "moveFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => -1, 'category_id' => 1],
['op' => "moveFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'category_id' => -1],
['op' => "moveFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42],
['op' => "moveFeed", 'sid' => "PriestsOfSyrinx", 'category_id' => -1],
['op' => "moveFeed", 'sid' => "PriestsOfSyrinx"],
];
$db = [
[Arsse::$user->id, 42, ['folder' => 1]],
[Arsse::$user->id, 2112, ['folder' => 2]],
[Arsse::$user->id, 42, ['folder' => 0]],
[Arsse::$user->id, 42, ['folder' => 47]],
public function provideFeedUnsubscriptions(): iterable {
return [
[['feed_id' => 42], [$this->userId, 42], true, $this->respGood(['status' => "OK"])],
[['feed_id' => 2112], [$this->userId, 2112], new ExceptionInput("subjectMissing"), $this->respErr("FEED_NOT_FOUND")],
[['feed_id' => -1], [$this->userId, -1], new ExceptionInput("typeViolation"), $this->respErr("FEED_NOT_FOUND")],
[[], [$this->userId, 0], new ExceptionInput("typeViolation"), $this->respErr("FEED_NOT_FOUND")],
];
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[0])->thenReturn(true);
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[1])->thenThrow(new ExceptionInput("subjectMissing"));
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[2])->thenThrow(new ExceptionInput("constraintViolation"));
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[3])->thenThrow(new ExceptionInput("constraintViolation"));
// succefully move a subscription
$exp = $this->respGood();
$this->assertMessage($exp, $this->req($in[0]));
// move a subscription which does not exist (this should silently fail)
$exp = $this->respGood();
$this->assertMessage($exp, $this->req($in[1]));
// move a subscription causing a duplication (this should also silently fail)
$exp = $this->respGood();
$this->assertMessage($exp, $this->req($in[2]));
$this->assertMessage($exp, $this->req($in[3]));
// all the rest should cause errors
$exp = $this->respErr("INCORRECT_USAGE");
$this->assertMessage($exp, $this->req($in[4]));
$this->assertMessage($exp, $this->req($in[5]));
$this->assertMessage($exp, $this->req($in[6]));
$this->assertMessage($exp, $this->req($in[7]));
$this->assertMessage($exp, $this->req($in[8]));
\Phake::verify(Arsse::$db, \Phake::times(4))->subscriptionPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything());
}
public function testRenameASubscription(): void {
$in = [
['op' => "renameFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'caption' => "Ook"],
['op' => "renameFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112, 'caption' => "Eek"],
['op' => "renameFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'caption' => "Eek"],
['op' => "renameFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'caption' => ""],
['op' => "renameFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'caption' => " "],
['op' => "renameFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => -1, 'caption' => "Ook"],
['op' => "renameFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42],
['op' => "renameFeed", 'sid' => "PriestsOfSyrinx", 'caption' => "Ook"],
['op' => "renameFeed", 'sid' => "PriestsOfSyrinx"],
/** @dataProvider provideFeedMoves */
public function testMoveAFeed(array $in, ?array $data, $out, ResponseInterface $exp): void {
$in = array_merge(['op' => "moveFeed", 'sid' => "PriestsOfSyrinx"], $in);
$action = ($out instanceof \Exception) ? "throws" : "returns";
$this->dbMock->subscriptionPropertiesSet->$action($out);
$this->assertMessage($exp, $this->req($in));
if ($out !== null) {
$this->dbMock->subscriptionPropertiesSet->calledWith(...$data);
} else {
$this->dbMock->subscriptionPropertiesSet->never()->called();
}
}
public function provideFeedMoves(): iterable {
return [
[['feed_id' => 42, 'category_id' => 1], [$this->userId, 42, ['folder' => 1]], true, $this->respGood()],
[['feed_id' => 2112, 'category_id' => 2], [$this->userId, 2112, ['folder' => 2]], new ExceptionInput("subjectMissing"), $this->respGood()],
[['feed_id' => 42, 'category_id' => 0], [$this->userId, 42, ['folder' => 0]], new ExceptionInput("constraintViolation"), $this->respGood()],
[['feed_id' => 42, 'category_id' => 47], [$this->userId, 42, ['folder' => 47]], new ExceptionInput("constraintViolation"), $this->respGood()],
[['feed_id' => -1, 'category_id' => 1], null, null, $this->respErr("INCORRECT_USAGE")],
[['feed_id' => 42, 'category_id' => -1], null, null, $this->respErr("INCORRECT_USAGE")],
[['feed_id' => 42], null, null, $this->respErr("INCORRECT_USAGE")],
[['category_id' => -1], null, null, $this->respErr("INCORRECT_USAGE")],
[[], null, null, $this->respErr("INCORRECT_USAGE")],
];
$db = [
[Arsse::$user->id, 42, ['title' => "Ook"]],
[Arsse::$user->id, 2112, ['title' => "Eek"]],
[Arsse::$user->id, 42, ['title' => "Eek"]],
}
/** @dataProvider provideFeedRenamings */
public function testRenameAFeed(array $in, ?array $data, $out, ResponseInterface $exp): void {
$in = array_merge(['op' => "renameFeed", 'sid' => "PriestsOfSyrinx"], $in);
$action = ($out instanceof \Exception) ? "throws" : "returns";
$this->dbMock->subscriptionPropertiesSet->$action($out);
$this->assertMessage($exp, $this->req($in));
if ($out !== null) {
$this->dbMock->subscriptionPropertiesSet->calledWith(...$data);
} else {
$this->dbMock->subscriptionPropertiesSet->never()->called();
}
}
public function provideFeedRenamings(): iterable {
return [
[['feed_id' => 42, 'caption' => "Ook"], [$this->userId, 42, ['title' => "Ook"]], true, $this->respGood()],
[['feed_id' => 2112, 'caption' => "Eek"], [$this->userId, 2112, ['title' => "Eek"]], new ExceptionInput("subjectMissing"), $this->respGood()],
[['feed_id' => 42, 'caption' => "Eek"], [$this->userId, 42, ['title' => "Eek"]], new ExceptionInput("constraintViolation"), $this->respGood()],
[['feed_id' => 42, 'caption' => ""], null, null, $this->respErr("INCORRECT_USAGE")],
[['feed_id' => 42, 'caption' => " "], null, null, $this->respErr("INCORRECT_USAGE")],
[['feed_id' => -1, 'caption' => "Ook"], null, null, $this->respErr("INCORRECT_USAGE")],
[['feed_id' => 42], null, null, $this->respErr("INCORRECT_USAGE")],
[['caption' => "Ook"], null, null, $this->respErr("INCORRECT_USAGE")],
[[], null, null, $this->respErr("INCORRECT_USAGE")],
];
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[0])->thenReturn(true);
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[1])->thenThrow(new ExceptionInput("subjectMissing"));
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(...$db[2])->thenThrow(new ExceptionInput("constraintViolation"));
// succefully rename a subscription
$exp = $this->respGood();
$this->assertMessage($exp, $this->req($in[0]));
// rename a subscription which does not exist (this should silently fail)
$exp = $this->respGood();
$this->assertMessage($exp, $this->req($in[1]));
// rename a subscription causing a duplication (this should also silently fail)
$exp = $this->respGood();
$this->assertMessage($exp, $this->req($in[2]));
// all the rest should cause errors
$exp = $this->respErr("INCORRECT_USAGE");
$this->assertMessage($exp, $this->req($in[3]));
$this->assertMessage($exp, $this->req($in[4]));
$this->assertMessage($exp, $this->req($in[5]));
$this->assertMessage($exp, $this->req($in[6]));
$this->assertMessage($exp, $this->req($in[7]));
$this->assertMessage($exp, $this->req($in[8]));
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet(...$db[0]);
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet(...$db[1]);
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet(...$db[2]);
}
public function testRetrieveTheGlobalUnreadCount(): void {
@ -866,76 +836,69 @@ LONG_STRING;
$interval = Arsse::$conf->serviceFrequency;
$valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval);
$invalid = $valid->sub($interval)->sub($interval);
$this->dbMock->metaGet->with("service_last_checkin")->returns(Date::transform($valid, "sql"))->returns(Date::transform($invalid, "sql"));
$this->dbMock->metaGet->with("service_last_checkin")->returns(Date::transform($valid, "sql"), Date::transform($invalid, "sql"));
$this->dbMock->subscriptionCount->with($this->userId)->returns(12, 2);
$this->assertMessage($this->respGood(['icons_dir' => "feed-icons", 'icons_url' => "feed-icons", 'daemon_is_running' => true, 'num_feeds' => 12]), $this->req($in));
$this->assertMessage($this->respGood(['icons_dir' => "feed-icons", 'icons_url' => "feed-icons", 'daemon_is_running' => false, 'num_feeds' => 2]), $this->req($in));
}
public function testUpdateAFeed(): void {
$in = [
['op' => "updateFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 1],
['op' => "updateFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2],
['op' => "updateFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => -1],
['op' => "updateFeed", 'sid' => "PriestsOfSyrinx"],
];
\Phake::when(Arsse::$db)->feedUpdate(11)->thenReturn(true);
\Phake::when(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 1)->thenReturn($this->v(['id' => 1, 'feed' => 11]));
\Phake::when(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 2)->thenThrow(new ExceptionInput("subjectMissing"));
$exp = $this->respGood(['status' => "OK"]);
$this->assertMessage($exp, $this->req($in[0]));
\Phake::verify(Arsse::$db)->feedUpdate(11);
$exp = $this->respErr("FEED_NOT_FOUND");
$this->assertMessage($exp, $this->req($in[1]));
$exp = $this->respErr("INCORRECT_USAGE");
$this->assertMessage($exp, $this->req($in[2]));
$this->assertMessage($exp, $this->req($in[3]));
/** @dataProvider provideFeedUpdates */
public function testUpdateAFeed(array $in, ?array $data, $out, ?int $id, ResponseInterface $exp): void {
$in = array_merge(['op' => "updateFeed", 'sid' => "PriestsOfSyrinx"], $in);
$action = ($out instanceof \Exception) ? "throws" : "returns";
$this->dbMock->subscriptionPropertiesGet->$action($out);
$this->dbMock->feedUpdate->returns(true);
$this->assertMessage($exp, $this->req($in));
if ($data !== null) {
$this->dbMock->subscriptionPropertiesGet->calledWith(...$data);
} else {
$this->dbMock->subscriptionPropertiesGet->never()->called();
}
if ($id !== null) {
$this->dbMock->feedUpdate->calledWith($id);
} else {
$this->dbMock->feedUpdate->never()->called();
}
}
public function testAddALabel(): void {
$in = [
['op' => "addLabel", 'sid' => "PriestsOfSyrinx", 'caption' => "Software"],
['op' => "addLabel", 'sid' => "PriestsOfSyrinx", 'caption' => "Hardware"],
['op' => "addLabel", 'sid' => "PriestsOfSyrinx"],
['op' => "addLabel", 'sid' => "PriestsOfSyrinx", 'caption' => ""],
['op' => "addLabel", 'sid' => "PriestsOfSyrinx", 'caption' => " "],
];
$db = [
['name' => "Software"],
['name' => "Hardware"],
public function provideFeedUpdates(): iterable {
return [
[['feed_id' => 1], [$this->userId, 1], $this->v(['id' => 1, 'feed' => 11]), 11, $this->respGood(['status' => "OK"])],
[['feed_id' => 2], [$this->userId, 2], new ExceptionInput("subjectMissing"), null, $this->respErr("FEED_NOT_FOUND")],
[['feed_id' => -1], null, null, null, $this->respErr("INCORRECT_USAGE")],
[[], null, null, null, $this->respErr("INCORRECT_USAGE")],
];
$out = [
['id' => 2, 'name' => "Software"],
['id' => 3, 'name' => "Hardware"],
['id' => 1, 'name' => "Politics"],
}
/** @dataProvider provideLabelAdditions */
public function testAddALabel(array $in, ?array $data1, $out1, ?array $data2, $out2, ResponseInterface $exp): void {
$in = array_merge(['op' => "addLabel", 'sid' => "PriestsOfSyrinx"], $in);
$action = ($out1 instanceof \Exception) ? "throws" : "returns";
$this->dbMock->labelAdd->$action($out1);
$this->dbMock->labelPropertiesGet->returns($out2);
$this->assertMessage($exp, $this->req($in));
if ($out1 !== null) {
$this->dbMock->labelAdd->calledWith(...$data1);
} else {
$this->dbMock->labelAdd->never()->called();
}
if ($out2 !== null) {
$this->dbMock->labelPropertiesGet->calledWith(...$data2);
} else {
$this->dbMock->labelPropertiesGet->never()->called();
}
}
public function provideLabelAdditions(): iterable {
return [
[['caption' => "Software"], [$this->userId, ['name' => "Software"]], 2, null, null, $this->respGood(-1026)],
[['caption' => "Hardware"], [$this->userId, ['name' => "Hardware"]], 3, null, null, $this->respGood(-1027)],
[['caption' => "Software"], [$this->userId, ['name' => "Software"]], new ExceptionInput("constraintViolation"), [$this->userId, "Software", true], ['id' => 2], $this->respGood(-1026)],
[['caption' => "Hardware"], [$this->userId, ['name' => "Hardware"]], new ExceptionInput("constraintViolation"), [$this->userId, "Hardware", true], ['id' => 3], $this->respGood(-1027)],
[[], [$this->userId, ['name' => ""]], new ExceptionInput("typeViolation"), null, null, $this->respErr("INCORRECT_USAGE")],
[['caption' => ""], [$this->userId, ['name' => ""]], new ExceptionInput("typeViolation"), null, null, $this->respErr("INCORRECT_USAGE")],
[['caption' => " "], [$this->userId, ['name' => " "]], new ExceptionInput("typeViolation"), null, null, $this->respErr("INCORRECT_USAGE")],
];
$labelOffset = (new \ReflectionClassConstant(API::class, "LABEL_OFFSET"))->getValue();
// set of various mocks for testing
\Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, $db[0])->thenReturn(2)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call
\Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, $db[1])->thenReturn(3)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call
\Phake::when(Arsse::$db)->labelPropertiesGet(Arsse::$user->id, "Software", true)->thenReturn($this->v($out[0]));
\Phake::when(Arsse::$db)->labelPropertiesGet(Arsse::$user->id, "Hardware", true)->thenReturn($this->v($out[1]));
// set up mocks that produce errors
\Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, [])->thenThrow(new ExceptionInput("missing"));
\Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, ['name' => ""])->thenThrow(new ExceptionInput("missing"));
\Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, ['name' => " "])->thenThrow(new ExceptionInput("whitespace"));
// correctly add two labels
$exp = $this->respGood((-1 * $labelOffset) - 2);
$this->assertMessage($exp, $this->req($in[0]));
$exp = $this->respGood((-1 * $labelOffset) - 3);
$this->assertMessage($exp, $this->req($in[1]));
// attempt to add the two labels again
$exp = $this->respGood((-1 * $labelOffset) - 2);
$this->assertMessage($exp, $this->req($in[0]));
$exp = $this->respGood((-1 * $labelOffset) - 3);
$this->assertMessage($exp, $this->req($in[1]));
\Phake::verify(Arsse::$db)->labelPropertiesGet(Arsse::$user->id, "Software", true);
\Phake::verify(Arsse::$db)->labelPropertiesGet(Arsse::$user->id, "Hardware", true);
// add some invalid labels
$exp = $this->respErr("INCORRECT_USAGE");
$this->assertMessage($exp, $this->req($in[2]));
$this->assertMessage($exp, $this->req($in[3]));
$this->assertMessage($exp, $this->req($in[4]));
}
public function testRemoveALabel(): void {

Loading…
Cancel
Save