The clean & modern RSS server that doesn't give you any crap. https://thearsse.com/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

338 lines
16 KiB

<?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\Arsse;
use JKingWeb\Arsse\Database;
trait SeriesTag {
protected static $drv;
protected $checkMembers;
protected $checkTags;
protected function setUpSeriesTag(): void {
$this->data = [
'arsse_users' => [
'columns' => ["id", "password", "num"],
'rows' => [
["jane.doe@example.com", "", 1],
["john.doe@example.com", "", 2],
["john.doe@example.org", "", 3],
["john.doe@example.net", "", 4],
],
],
'arsse_subscriptions' => [
'columns' => ["id", "owner", "url", "feed_title", "title", "deleted"],
'rows' => [
[1, "john.doe@example.com", "http://example.com/1", "", "Lord of Carrots", 0],
[2, "john.doe@example.com", "http://example.com/2", "", null, 0],
[3, "john.doe@example.com", "http://example.com/3", "Feed Title", "Subscription Title", 0],
[4, "john.doe@example.com", "http://example.com/4", "", null, 0],
[5, "john.doe@example.com", "http://example.com/10", "", null, 0],
[6, "jane.doe@example.com", "http://example.com/1", "", null, 0],
[7, "jane.doe@example.com", "http://example.com/10", "", null, 0],
[8, "john.doe@example.org", "http://example.com/11", "", null, 0],
[9, "john.doe@example.org", "http://example.com/12", "", null, 0],
[10, "john.doe@example.org", "http://example.com/13", "", null, 0],
[11, "john.doe@example.net", "http://example.com/10", "", null, 0],
[12, "john.doe@example.net", "http://example.com/2", "", null, 0],
[13, "john.doe@example.net", "http://example.com/3", "Feed Title", null, 0],
[14, "john.doe@example.net", "http://example.com/4", "", null, 0],
[16, "john.doe@example.com", "http://example.com/16", "", null, 1],
],
],
'arsse_tags' => [
'columns' => ["id", "owner", "name"],
'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_tag_members' => [
'columns' => ["tag", "subscription", "assigned"],
'rows' => [
[1, 1,1],
[1, 3,0],
[1, 5,1],
[2, 1,1],
[2, 3,1],
[2, 5,1],
[1,16,1],
[2,16,1],
],
],
];
$this->checkTags = ['arsse_tags' => ["id","owner","name"]];
$this->checkMembers = ['arsse_tag_members' => ["tag","subscription","assigned"]];
$this->user = "john.doe@example.com";
}
protected function tearDownSeriesTag(): void {
unset($this->data, $this->checkTags, $this->checkMembers, $this->user);
}
public function testAddATag(): void {
$user = "john.doe@example.com";
$tagID = $this->nextID("arsse_tags");
$this->assertSame($tagID, Arsse::$db->tagAdd($user, ['name' => "Entertaining"]));
$state = $this->primeExpectations($this->data, $this->checkTags);
$state['arsse_tags']['rows'][] = [$tagID, $user, "Entertaining"];
$this->compareExpectations(static::$drv, $state);
}
public function testAddADuplicateTag(): void {
$this->assertException("constraintViolation", "Db", "ExceptionInput");
Arsse::$db->tagAdd("john.doe@example.com", ['name' => "Interesting"]);
}
public function testAddATagWithAMissingName(): void {
$this->assertException("missing", "Db", "ExceptionInput");
Arsse::$db->tagAdd("john.doe@example.com", []);
}
public function testAddATagWithABlankName(): void {
$this->assertException("missing", "Db", "ExceptionInput");
Arsse::$db->tagAdd("john.doe@example.com", ['name' => ""]);
}
public function testAddATagWithAWhitespaceName(): void {
$this->assertException("whitespace", "Db", "ExceptionInput");
Arsse::$db->tagAdd("john.doe@example.com", ['name' => " "]);
}
public function testListTags(): void {
$exp = [
['id' => 2, 'name' => "Fascinating", 'subscriptions' => 3],
['id' => 1, 'name' => "Interesting", 'subscriptions' => 2],
['id' => 4, 'name' => "Lonely", 'subscriptions' => 0],
];
$this->assertResult($exp, Arsse::$db->tagList("john.doe@example.com"));
$exp = [
['id' => 3, 'name' => "Boring", 'subscriptions' => 0],
];
$this->assertResult($exp, Arsse::$db->tagList("jane.doe@example.com"));
$exp = [];
$this->assertResult($exp, Arsse::$db->tagList("jane.doe@example.com", false));
}
public function testRemoveATag(): void {
$this->assertTrue(Arsse::$db->tagRemove("john.doe@example.com", 1));
$state = $this->primeExpectations($this->data, $this->checkTags);
array_shift($state['arsse_tags']['rows']);
$this->compareExpectations(static::$drv, $state);
}
public function testRemoveATagByName(): void {
$this->assertTrue(Arsse::$db->tagRemove("john.doe@example.com", "Interesting", true));
$state = $this->primeExpectations($this->data, $this->checkTags);
array_shift($state['arsse_tags']['rows']);
$this->compareExpectations(static::$drv, $state);
}
public function testRemoveAMissingTag(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tagRemove("john.doe@example.com", 2112);
}
public function testRemoveAnInvalidTag(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->tagRemove("john.doe@example.com", -1);
}
public function testRemoveAnInvalidTagByName(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->tagRemove("john.doe@example.com", [], true);
}
public function testRemoveATagOfTheWrongOwner(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tagRemove("john.doe@example.com", 3); // tag ID 3 belongs to Jane
}
public function testGetThePropertiesOfATag(): void {
$exp = [
'id' => 2,
'name' => "Fascinating",
];
$this->assertArraySubset($exp, Arsse::$db->tagPropertiesGet("john.doe@example.com", 2));
$this->assertArraySubset($exp, Arsse::$db->tagPropertiesGet("john.doe@example.com", "Fascinating", true));
}
public function testGetThePropertiesOfAMissingTag(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesGet("john.doe@example.com", 2112);
}
public function testGetThePropertiesOfAnInvalidTag(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesGet("john.doe@example.com", -1);
}
public function testGetThePropertiesOfAnInvalidTagByName(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesGet("john.doe@example.com", [], true);
}
public function testGetThePropertiesOfATagOfTheWrongOwner(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesGet("john.doe@example.com", 3); // tag ID 3 belongs to Jane
}
public function testMakeNoChangesToATag(): void {
$this->assertFalse(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, []));
}
public function testRenameATag(): void {
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Curious"]));
$state = $this->primeExpectations($this->data, $this->checkTags);
$state['arsse_tags']['rows'][0][2] = "Curious";
$this->compareExpectations(static::$drv, $state);
}
public function testRenameATagByName(): void {
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", "Interesting", ['name' => "Curious"], true));
$state = $this->primeExpectations($this->data, $this->checkTags);
$state['arsse_tags']['rows'][0][2] = "Curious";
$this->compareExpectations(static::$drv, $state);
}
public function testRenameATagToTheEmptyString(): void {
$this->assertException("missing", "Db", "ExceptionInput");
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => ""]));
}
public function testRenameATagToWhitespaceOnly(): void {
$this->assertException("whitespace", "Db", "ExceptionInput");
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => " "]));
}
public function testRenameATagToAnInvalidValue(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput");
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => []]));
}
public function testCauseATagCollision(): void {
$this->assertException("constraintViolation", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Fascinating"]);
}
public function testSetThePropertiesOfAMissingTag(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesSet("john.doe@example.com", 2112, ['name' => "Exciting"]);
}
public function testSetThePropertiesOfAnInvalidTag(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesSet("john.doe@example.com", -1, ['name' => "Exciting"]);
}
public function testSetThePropertiesOfAnInvalidTagByName(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesSet("john.doe@example.com", [], ['name' => "Exciting"], true);
}
public function testSetThePropertiesOfATagForTheWrongOwner(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesSet("john.doe@example.com", 3, ['name' => "Exciting"]); // tag ID 3 belongs to Jane
}
public function testListTaggedSubscriptions(): void {
$exp = [1,5];
$this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 1));
$this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", "Interesting", true));
$exp = [1,3,5];
$this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 2));
$this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", "Fascinating", true));
$exp = [];
$this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 4));
$this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", "Lonely", true));
}
public function testListTaggedSubscriptionsForAMissingTag(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 3);
}
public function testListTaggedSubscriptionsForAnInvalidTag(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->tagSubscriptionsGet("john.doe@example.com", -1);
}
public function testApplyATagToSubscriptions(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [3,4]);
$state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_tag_members']['rows'][1][2] = 1;
$state['arsse_tag_members']['rows'][] = [1,4,1];
$this->compareExpectations(static::$drv, $state);
}
public function testClearATagFromSubscriptions(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [1,3], Database::ASSOC_REMOVE);
$state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_tag_members']['rows'][0][2] = 0;
$this->compareExpectations(static::$drv, $state);
}
public function testApplyATagToSubscriptionsByName(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [3,4], Database::ASSOC_ADD, true);
$state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_tag_members']['rows'][1][2] = 1;
$state['arsse_tag_members']['rows'][] = [1,4,1];
$this->compareExpectations(static::$drv, $state);
}
public function testClearATagFromSubscriptionsByName(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [1,3], Database::ASSOC_REMOVE, true);
$state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_tag_members']['rows'][0][2] = 0;
$this->compareExpectations(static::$drv, $state);
}
public function testApplyATagToNoSubscriptionsByName(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [], Database::ASSOC_ADD, true);
$state = $this->primeExpectations($this->data, $this->checkMembers);
$this->compareExpectations(static::$drv, $state);
}
public function testClearATagFromNoSubscriptionsByName(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [], Database::ASSOC_REMOVE, true);
$state = $this->primeExpectations($this->data, $this->checkMembers);
$this->compareExpectations(static::$drv, $state);
}
public function testReplaceSubscriptionsOfATag(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [3,4], Database::ASSOC_REPLACE);
$state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_tag_members']['rows'][0][2] = 0;
$state['arsse_tag_members']['rows'][1][2] = 1;
$state['arsse_tag_members']['rows'][2][2] = 0;
$state['arsse_tag_members']['rows'][] = [1,4,1];
$this->compareExpectations(static::$drv, $state);
}
public function testPurgeSubscriptionsOfATag(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [], Database::ASSOC_REPLACE);
$state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_tag_members']['rows'][0][2] = 0;
$state['arsse_tag_members']['rows'][2][2] = 0;
$this->compareExpectations(static::$drv, $state);
}
public function testSummarizeTags(): void {
$exp = [
['id' => 1, 'name' => "Interesting", 'subscription' => 1],
['id' => 1, 'name' => "Interesting", 'subscription' => 5],
['id' => 2, 'name' => "Fascinating", 'subscription' => 1],
['id' => 2, 'name' => "Fascinating", 'subscription' => 3],
['id' => 2, 'name' => "Fascinating", 'subscription' => 5],
];
$this->assertResult($exp, Arsse::$db->tagSummarize("john.doe@example.com"));
}
}