mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 13:12:41 +00:00
Feed tests: article matching
These should be the last required tests for the Feed class
This commit is contained in:
parent
3e5343e3e8
commit
5b8f23441c
8 changed files with 402 additions and 68 deletions
|
@ -658,14 +658,14 @@ class Database {
|
|||
return true;
|
||||
}
|
||||
|
||||
public function articleMatchLatest(int $feedID, int $count): Db\Result {
|
||||
public function feedMatchLatest(int $feedID, int $count): Db\Result {
|
||||
return $this->db->prepare(
|
||||
'SELECT id, DATEFORMAT("unix", edited) AS edited_date, guid, url_title_hash, url_content_hash, title_content_hash FROM arsse_articles WHERE feed is ? ORDER BY edited desc limit ?',
|
||||
'int', 'int'
|
||||
)->run($feedID, $count);
|
||||
}
|
||||
|
||||
public function articleMatchIds(int $feedID, array $ids = [], array $hashesUT = [], array $hashesUC = [], array $hashesTC = []): Db\Result {
|
||||
public function feedMatchIds(int $feedID, array $ids = [], array $hashesUT = [], array $hashesUC = [], array $hashesTC = []): Db\Result {
|
||||
// compile SQL IN() clauses and necessary type bindings for the four identifier lists
|
||||
list($cId, $tId) = $this->generateIn($ids, "str");
|
||||
list($cHashUT, $tHashUT) = $this->generateIn($hashesUT, "str");
|
||||
|
|
95
lib/Feed.php
95
lib/Feed.php
|
@ -127,7 +127,7 @@ class Feed {
|
|||
}
|
||||
|
||||
// If there aren't any of those there is no id.
|
||||
$f->id = '';
|
||||
$f->id = null;
|
||||
}
|
||||
$this->data = $feed;
|
||||
return true;
|
||||
|
@ -184,11 +184,30 @@ class Feed {
|
|||
return true;
|
||||
}
|
||||
// get as many of the latest articles in the database as there are in the feed
|
||||
$articles = Data::$db->articleMatchLatest($feedID, sizeof($items));
|
||||
// arrays holding new, edited, and tentatively new items; items may be tentatively new because we perform two passes
|
||||
$new = $tentative = $edited = [];
|
||||
$articles = Data::$db->feedMatchLatest($feedID, sizeof($items))->getAll();
|
||||
// perform a first pass matching the latest articles against items in the feed
|
||||
list($this->newItems, $this->changedItems) = $this->matchItems($items, $articles);
|
||||
if(sizeof($this->newItems) && sizeof($items) <= sizeof($articles)) {
|
||||
// if we need to, perform a second pass on the database looking specifically for IDs and hashes of the new items
|
||||
$ids = $hashesUT = $hashesUC = $hashesTC = [];
|
||||
foreach($this->newItems as $i) {
|
||||
if($i->id) $ids[] = $i->id;
|
||||
if($i->urlTitleHash) $hashesUT[] = $i->urlTitleHash;
|
||||
if($i->urlContentHash) $hashesUC[] = $i->urlContentHash;
|
||||
if($i->titleContentHash) $hashesTC[] = $i->titleContentHash;
|
||||
}
|
||||
$articles = Data::$db->feedMatchIds($feedID, $ids, $hashesUT, $hashesUC, $hashesTC)->getAll();
|
||||
list($this->newItems, $changed) = $this->matchItems($this->newItems, $articles);
|
||||
$this->changedItems = array_merge($this->changedItems, $changed);
|
||||
}
|
||||
// TODO: fetch full content when appropriate
|
||||
return true;
|
||||
}
|
||||
|
||||
public function matchItems(array $items, array $articles): array {
|
||||
$new = $edited = [];
|
||||
// iterate through the articles and for each determine whether it is existing, edited, or entirely new
|
||||
foreach($items as $index => $i) {
|
||||
foreach($items as $i) {
|
||||
$found = false;
|
||||
foreach($articles as $a) {
|
||||
// if the item has an ID and it doesn't match the article ID, the two don't match, regardless of hashes
|
||||
|
@ -201,16 +220,16 @@ class Feed {
|
|||
($i->urlContentHash && $i->urlContentHash === $a['url_content_hash']) ||
|
||||
($i->titleContentHash && $i->titleContentHash === $a['title_content_hash'])
|
||||
) {
|
||||
if($i->updatedDate && $i->updatedDate->getTimestamp() !== $match['edited_date']) {
|
||||
if($i->updatedDate && $i->updatedDate->getTimestamp() !== $a['edited_date']) {
|
||||
// if the item has an edit timestamp and it doesn't match that of the article in the database, the the article has been edited
|
||||
// we store the item index and database record ID as a key/value pair
|
||||
$found = true;
|
||||
$edited[$index] = $a['id'];
|
||||
$edited[$a['id']] = $i;
|
||||
break;
|
||||
} else if($i->urlTitleHash !== $a['url_title_hash'] || $i->urlContentHash !== $a['url_content_hash'] || $i->titleContentHash !== $a['title_content_hash']) {
|
||||
// if any of the hashes do not match, then the article has been edited
|
||||
$found = true;
|
||||
$edited[$index] = $a['id'];
|
||||
$edited[$a['id']] = $i;
|
||||
break;
|
||||
} else {
|
||||
// otherwise the item is unchanged and we can ignore it
|
||||
|
@ -219,65 +238,9 @@ class Feed {
|
|||
}
|
||||
}
|
||||
}
|
||||
if(!$found) $tentative[] = $index;
|
||||
if(!$found) $new[] = $i;
|
||||
}
|
||||
if(sizeof($tentative) && sizeof($items)==sizeof($articles)) {
|
||||
// if we need to, perform a second pass on the database looking specifically for IDs and hashes of the new items
|
||||
$ids = $hashesUT = $hashesUC = $hashesTC = [];
|
||||
foreach($tentative as $index) {
|
||||
$i = $items[$index];
|
||||
if($i->id) $ids[] = $i->id;
|
||||
if($i->urlTitleHash) $hashesUT[] = $i->urlTitleHash;
|
||||
if($i->urlContentHash) $hashesUC[] = $i->urlContentHash;
|
||||
if($i->titleContentHash) $hashesTC[] = $i->titleContentHash;
|
||||
}
|
||||
$articles = Data::$db->articleMatchIds($feedID, $ids, $hashesUT, $hashesUC, $hashesTC);
|
||||
foreach($tentative as $index) {
|
||||
$i = $items[$index];
|
||||
$found = false;
|
||||
foreach($articles as $a) {
|
||||
// if the item has an ID and it doesn't match the article ID, the two don't match, regardless of hashes
|
||||
if($i->id && $i->id !== $a['guid']) continue;
|
||||
if(
|
||||
// the item matches if the GUID matches...
|
||||
($i->id && $i->id === $a['guid']) ||
|
||||
// ... or if any one of the hashes match
|
||||
($i->urlTitleHash && $i->urlTitleHash === $a['url_title_hash']) ||
|
||||
($i->urlContentHash && $i->urlContentHash === $a['url_content_hash']) ||
|
||||
($i->titleContentHash && $i->titleContentHash === $a['title_content_hash'])
|
||||
) {
|
||||
if($i->updatedDate && $i->updatedDate->getTimestamp() !== $match['edited_date']) {
|
||||
// if the item has an edit timestamp and it doesn't match that of the article in the database, the the article has been edited
|
||||
// we store the item index and database record ID as a key/value pair
|
||||
$found = true;
|
||||
$edited[$index] = $a['id'];
|
||||
break;
|
||||
} else if($i->urlTitleHash !== $a['url_title_hash'] || $i->urlContentHash !== $a['url_content_hash'] || $i->titleContentHash !== $a['title_content_hash']) {
|
||||
// if any of the hashes do not match, then the article has been edited
|
||||
$found = true;
|
||||
$edited[$index] = $a['id'];
|
||||
break;
|
||||
} else {
|
||||
// otherwise the item is unchanged and we can ignore it
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!$found) $new[] = $index;
|
||||
}
|
||||
} else {
|
||||
// if there are no tentatively new articles and/or the number of stored articles is less than the size of the feed, don't do a second pass; assume any tentatively new items are in fact new
|
||||
$new = $tentative;
|
||||
}
|
||||
// TODO: fetch full content when appropriate
|
||||
foreach($new as $index) {
|
||||
$this->newItems[] = $items[$index];
|
||||
}
|
||||
foreach($edited as $index => $id) {
|
||||
$this->changedItems[$id] = $items[$index];
|
||||
}
|
||||
return true;
|
||||
return [$new, $edited];
|
||||
}
|
||||
|
||||
public function computeNextFetch(): \DateTime {
|
||||
|
|
|
@ -9,6 +9,74 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
|
|||
|
||||
protected static $host = "http://localhost:8000/";
|
||||
protected $base = "";
|
||||
protected $latest = [
|
||||
[
|
||||
'id' => 1,
|
||||
'edited_date' => 946684800,
|
||||
'guid' => 'e433653cef2e572eee4215fa299a4a5af9137b2cefd6283c85bd69a32915beda',
|
||||
'url_title_hash' => 'f5cb8bfc1c7396dc9816af212a3e2ac5221585c2a00bf7ccb6aabd95dcfcd6a6',
|
||||
'url_content_hash' => 'fb0bc8f8cb08913dc5a497db700e327f1d34e4987402687d494a5891f24714d4',
|
||||
'title_content_hash' => '18fdd4fa93d693128c43b004399e5c9cea6c261ddfa002518d3669f55d8c2207',
|
||||
],
|
||||
[
|
||||
'id' => 2,
|
||||
'edited_date' => 946771200,
|
||||
'guid' => '5be8a5a46ecd52ed132191c8d27fb1af6b3d4edc00234c5d9f8f0e10562ed3b7',
|
||||
'url_title_hash' => '0e86d2de822a174fe3c44a466953e63ca1f1a58a19cbf475fce0855d4e3d5153',
|
||||
'url_content_hash' => '13075894189c47ffcfafd1dfe7fbb539f7c74a69d35a399b3abf8518952714f9',
|
||||
'title_content_hash' => '2abd0a8cba83b8214a66c8f0293ba63e467d720540e29ff8ddcdab069d4f1c9e',
|
||||
],
|
||||
[
|
||||
'id' => 3,
|
||||
'edited_date' => 946857600,
|
||||
'guid' => '31a6594500a48b59fcc8a075ce82b946c9c3c782460d088bd7b8ef3ede97ad92',
|
||||
'url_title_hash' => 'f74b06b240bd08abf4d3fdfc20dba6a6f6eb8b4f1a00e9a617efd63a87180a4b',
|
||||
'url_content_hash' => 'b278380e984cefe63f0e412b88ffc9cb0befdfa06fdc00bace1da99a8daff406',
|
||||
'title_content_hash' => 'ad622b31e739cd3a3f3c788991082cf4d2f7a8773773008e75f0572e58cd373b',
|
||||
],
|
||||
[
|
||||
'id' => 4,
|
||||
'edited_date' => 946944000,
|
||||
'guid' => '804e517d623390e71497982c77cf6823180342ebcd2e7d5e32da1e55b09dd180',
|
||||
'url_title_hash' => 'f3615c7f16336d3ea242d35cf3fc17dbc4ee3afb78376bf49da2dd7a5a25dec8',
|
||||
'url_content_hash' => 'f11c2b4046f207579aeb9c69a8c20ca5461cef49756ccfa5ba5e2344266da3b3',
|
||||
'title_content_hash' => 'ab2da63276acce431250b18d3d49b988b226a99c7faadf275c90b751aee05be9',
|
||||
],
|
||||
[
|
||||
'id' => 5,
|
||||
'edited_date' => 947030400,
|
||||
'guid' => 'db3e736c2c492f5def5c5da33ddcbea1824040e9ced2142069276b0a6e291a41',
|
||||
'url_title_hash' => 'd40da96e39eea6c55948ccbe9b3d275b5f931298288dbe953990c5f496097022',
|
||||
'url_content_hash' => '834240f84501b5341d375414718204ec421561f3825d34c22bf9182203e42900',
|
||||
'title_content_hash' => '43b970ac6ec5f8a9647b2c7e4eed8b1d7f62e154a95eed748b0294c1256764ba',
|
||||
],
|
||||
];
|
||||
protected $others = [
|
||||
[
|
||||
'id' => 6,
|
||||
'edited_date' => 947116800,
|
||||
'guid' => 'b3461ab8e8759eeb1d65a818c65051ec00c1dfbbb32a3c8f6999434e3e3b76ab',
|
||||
'url_title_hash' => '91d051a8e6749d014506848acd45e959af50bf876427c4f0e3a1ec0f04777b51',
|
||||
'url_content_hash' => '211d78b1a040d40d17e747a363cc283f58767b2e502630d8de9b8f1d5e941d18',
|
||||
'title_content_hash' => '5ed68ccb64243b8c1931241d2c9276274c3b1d87f223634aa7a1ab0141292ca7',
|
||||
],
|
||||
[
|
||||
'id' => 7,
|
||||
'edited_date' => 947203200,
|
||||
'guid' => 'f4fae999d6531747523f4ff0c74f3f0c7c588b67e4f32d8f7dba5f6f36e8a45d',
|
||||
'url_title_hash' => 'b92f805f0d0643dad1d6c0bb5cbaec24729f5f71b37b831cf7ad31f6c9403ac8',
|
||||
'url_content_hash' => '4fc8789b787246e9be08ca1bac0d4a1ac4db1984f0db07f7142417598cf7211f',
|
||||
'title_content_hash' => '491df9338740b5297b3a3e8292be992ac112eb676c34595f7a38f3ee646ffe84',
|
||||
],
|
||||
[
|
||||
'id' => 8,
|
||||
'edited_date' => 947289600,
|
||||
'guid' => 'b9d2d58e3172096b1d23b42a59961fabc89962836c3cd5de54f3d3a98ff08e6c',
|
||||
'url_title_hash' => '53a6cbcfeb66b46d09cbb7b25035df0562da35786933319c83b04be29acfb6f4',
|
||||
'url_content_hash' => 'c6f3722b4445b49d19d39c3bf5b11a7cf23dd69873e2a0a458aab662f1cd9438',
|
||||
'title_content_hash' => '607d2da48807ca984ce2a9faa1d291bd9e3de9e912f83306167f4f5cd3c23bbd',
|
||||
],
|
||||
];
|
||||
|
||||
function setUp() {
|
||||
if(!@file_get_contents(self::$host."IsUp")) {
|
||||
|
@ -19,6 +87,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
|
|||
$this->base = self::$host."Feed/";
|
||||
$this->clearData();
|
||||
Data::$conf = new Conf();
|
||||
Data::$db = Phake::mock(Database::class);
|
||||
}
|
||||
|
||||
function testHandle400() {
|
||||
|
@ -278,4 +347,28 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
|
|||
$exp = strtotime("now + 1 hour");
|
||||
$this->assertTime($exp, $f->nextFetch);
|
||||
}
|
||||
|
||||
function testMatchLatestArticles() {
|
||||
Phake::when(Data::$db)->feedMatchLatest(1, $this->anything())->thenReturn(new Test\Result($this->latest));
|
||||
$f = new Feed(1, $this->base."Matching/1");
|
||||
$this->assertCount(0, $f->newItems);
|
||||
$this->assertCount(0, $f->changedItems);
|
||||
$f = new Feed(1, $this->base."Matching/2");
|
||||
$this->assertCount(1, $f->newItems);
|
||||
$this->assertCount(0, $f->changedItems);
|
||||
$f = new Feed(1, $this->base."Matching/3");
|
||||
$this->assertCount(1, $f->newItems);
|
||||
$this->assertCount(2, $f->changedItems);
|
||||
$f = new Feed(1, $this->base."Matching/4");
|
||||
$this->assertCount(1, $f->newItems);
|
||||
$this->assertCount(2, $f->changedItems);
|
||||
}
|
||||
|
||||
function testMatchHistoricalArticles() {
|
||||
Phake::when(Data::$db)->feedMatchLatest(1, $this->anything())->thenReturn(new Test\Result($this->latest));
|
||||
Phake::when(Data::$db)->feedMatchIds(1, $this->anything(), $this->anything(), $this->anything(), $this->anything())->thenReturn(new Test\Result($this->others));
|
||||
$f = new Feed(1, $this->base."Matching/5");
|
||||
$this->assertCount(0, $f->newItems);
|
||||
$this->assertCount(0, $f->changedItems);
|
||||
}
|
||||
}
|
51
tests/docroot/Feed/Matching/1.php
Normal file
51
tests/docroot/Feed/Matching/1.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php return [
|
||||
'mime' => "application/atom+xml",
|
||||
'content' => <<<MESSAGE_BODY
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title>Example feed title</title>
|
||||
<id>urn:uuid:0fd8f6d8-43df-11e7-8511-9b59a0324eb8</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/"/>
|
||||
|
||||
<entry>
|
||||
<id>urn:uuid:df329114-43df-11e7-9f23-a938604d62f8</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/1"/>
|
||||
<title>Article title 1</title>
|
||||
<content>Article content 1</content>
|
||||
<published>2000-01-01T00:00:00Z</published>
|
||||
<updated>2000-01-01T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:24382fa8-43e0-11e7-bd9c-559df0ea4b9b</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/2"/>
|
||||
<title>Article title 2</title>
|
||||
<content>Article content 2</content>
|
||||
<published>2000-01-02T00:00:00Z</published>
|
||||
<updated>2000-01-02T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:03b9f558-43e1-11e7-87c5-ebaab4fd4cd1</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/3"/>
|
||||
<title>Article title 3</title>
|
||||
<content>Article content 3</content>
|
||||
<published>2000-01-03T00:00:00Z</published>
|
||||
<updated>2000-01-03T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:3d5f5154-43e1-11e7-ba11-1dcae392a974</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/4"/>
|
||||
<title>Article title 4</title>
|
||||
<content>Article content 4</content>
|
||||
<published>2000-01-04T00:00:00Z</published>
|
||||
<updated>2000-01-04T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:6d4c7964-43e1-11e7-92bd-4fed65d89793</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/5"/>
|
||||
<title>Article title 5</title>
|
||||
<content>Article content 5</content>
|
||||
<published>2000-01-05T00:00:00Z</published>
|
||||
<updated>2000-01-05T00:00:00Z</updated>
|
||||
</entry>
|
||||
</feed>
|
||||
MESSAGE_BODY
|
||||
];
|
59
tests/docroot/Feed/Matching/2.php
Normal file
59
tests/docroot/Feed/Matching/2.php
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php return [
|
||||
'mime' => "application/atom+xml",
|
||||
'content' => <<<MESSAGE_BODY
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title>Example feed title</title>
|
||||
<id>urn:uuid:0fd8f6d8-43df-11e7-8511-9b59a0324eb8</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/"/>
|
||||
|
||||
<entry>
|
||||
<id>urn:uuid:df329114-43df-11e7-9f23-a938604d62f8</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/1"/>
|
||||
<title>Article title 1</title>
|
||||
<content>Article content 1</content>
|
||||
<published>2000-01-01T00:00:00Z</published>
|
||||
<updated>2000-01-01T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:24382fa8-43e0-11e7-bd9c-559df0ea4b9b</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/2"/>
|
||||
<title>Article title 2</title>
|
||||
<content>Article content 2</content>
|
||||
<published>2000-01-02T00:00:00Z</published>
|
||||
<updated>2000-01-02T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:03b9f558-43e1-11e7-87c5-ebaab4fd4cd1</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/3"/>
|
||||
<title>Article title 3</title>
|
||||
<content>Article content 3</content>
|
||||
<published>2000-01-03T00:00:00Z</published>
|
||||
<updated>2000-01-03T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:3d5f5154-43e1-11e7-ba11-1dcae392a974</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/4"/>
|
||||
<title>Article title 4</title>
|
||||
<content>Article content 4</content>
|
||||
<published>2000-01-04T00:00:00Z</published>
|
||||
<updated>2000-01-04T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:6d4c7964-43e1-11e7-92bd-4fed65d89793</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/5"/>
|
||||
<title>Article title 5</title>
|
||||
<content>Article content 5</content>
|
||||
<published>2000-01-05T00:00:00Z</published>
|
||||
<updated>2000-01-05T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:b0b9698c-43e6-11e7-85b4-53a6b351844b</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/6"/>
|
||||
<title>Article title 6</title>
|
||||
<content>Article content 6</content>
|
||||
<published>2000-01-06T00:00:00Z</published>
|
||||
<updated>2000-01-06T00:00:00Z</updated>
|
||||
</entry>
|
||||
</feed>
|
||||
MESSAGE_BODY
|
||||
];
|
59
tests/docroot/Feed/Matching/3.php
Normal file
59
tests/docroot/Feed/Matching/3.php
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php return [
|
||||
'mime' => "application/atom+xml",
|
||||
'content' => <<<MESSAGE_BODY
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title>Example feed title</title>
|
||||
<id>urn:uuid:0fd8f6d8-43df-11e7-8511-9b59a0324eb8</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/"/>
|
||||
|
||||
<entry>
|
||||
<id>urn:uuid:df329114-43df-11e7-9f23-a938604d62f8</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/1"/>
|
||||
<title>Article title 1</title>
|
||||
<content>Article content 1</content>
|
||||
<published>2000-01-01T00:00:00Z</published>
|
||||
<updated>2000-01-01T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:24382fa8-43e0-11e7-bd9c-559df0ea4b9b</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/2"/>
|
||||
<title>Article title 2</title>
|
||||
<content>Article content 2</content>
|
||||
<published>2000-01-02T00:00:00Z</published>
|
||||
<updated>2000-01-02T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:03b9f558-43e1-11e7-87c5-ebaab4fd4cd1</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/3"/>
|
||||
<title>Article title 3 (updated)</title>
|
||||
<content>Article content 3</content>
|
||||
<published>2000-01-03T00:00:00Z</published>
|
||||
<updated>2000-01-03T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:3d5f5154-43e1-11e7-ba11-1dcae392a974</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/4"/>
|
||||
<title>Article title 4</title>
|
||||
<content>Article content 4</content>
|
||||
<published>2000-01-04T00:00:00Z</published>
|
||||
<updated>2000-01-04T00:00:01Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:6d4c7964-43e1-11e7-92bd-4fed65d89793</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/5"/>
|
||||
<title>Article title 5</title>
|
||||
<content>Article content 5</content>
|
||||
<published>2000-01-05T00:00:00Z</published>
|
||||
<updated>2000-01-05T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:b0b9698c-43e6-11e7-85b4-53a6b351844b</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/6"/>
|
||||
<title>Article title 6</title>
|
||||
<content>Article content 6</content>
|
||||
<published>2000-01-06T00:00:00Z</published>
|
||||
<updated>2000-01-06T00:00:00Z</updated>
|
||||
</entry>
|
||||
</feed>
|
||||
MESSAGE_BODY
|
||||
];
|
58
tests/docroot/Feed/Matching/4.php
Normal file
58
tests/docroot/Feed/Matching/4.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php return [
|
||||
'mime' => "application/atom+xml",
|
||||
'content' => <<<MESSAGE_BODY
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title>Example feed title</title>
|
||||
<id>urn:uuid:0fd8f6d8-43df-11e7-8511-9b59a0324eb8</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/"/>
|
||||
|
||||
<entry>
|
||||
<id>urn:uuid:df329114-43df-11e7-9f23-a938604d62f8</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/1"/>
|
||||
<title>Article title 1</title>
|
||||
<content>Article content 1</content>
|
||||
<published>2000-01-01T00:00:00Z</published>
|
||||
<updated>2000-01-01T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:24382fa8-43e0-11e7-bd9c-559df0ea4b9b</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/2"/>
|
||||
<title>Article title 2</title>
|
||||
<content>Article content 2</content>
|
||||
<published>2000-01-02T00:00:00Z</published>
|
||||
<updated>2000-01-02T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:03b9f558-43e1-11e7-87c5-ebaab4fd4cd1</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/3"/>
|
||||
<title>Article title 3 (updated)</title>
|
||||
<content>Article content 3</content>
|
||||
<published>2000-01-03T00:00:00Z</published>
|
||||
<updated>2000-01-03T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/4"/>
|
||||
<title>Article title 4</title>
|
||||
<content>Article content 4 with updates</content>
|
||||
<published>2000-01-04T00:00:00Z</published>
|
||||
<updated>2000-01-04T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:6d4c7964-43e1-11e7-92bd-4fed65d89793</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/5"/>
|
||||
<title>Article title 5</title>
|
||||
<content>Article content 5</content>
|
||||
<published>2000-01-05T00:00:00Z</published>
|
||||
<updated>2000-01-05T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:b0b9698c-43e6-11e7-85b4-53a6b351844b</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/6"/>
|
||||
<title>Article title 6</title>
|
||||
<content>Article content 6</content>
|
||||
<published>2000-01-06T00:00:00Z</published>
|
||||
<updated>2000-01-06T00:00:00Z</updated>
|
||||
</entry>
|
||||
</feed>
|
||||
MESSAGE_BODY
|
||||
];
|
51
tests/docroot/Feed/Matching/5.php
Normal file
51
tests/docroot/Feed/Matching/5.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php return [
|
||||
'mime' => "application/atom+xml",
|
||||
'content' => <<<MESSAGE_BODY
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title>Example feed title</title>
|
||||
<id>urn:uuid:0fd8f6d8-43df-11e7-8511-9b59a0324eb8</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/"/>
|
||||
|
||||
<entry>
|
||||
<id>urn:uuid:3d5f5154-43e1-11e7-ba11-1dcae392a974</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/4"/>
|
||||
<title>Article title 4</title>
|
||||
<content>Article content 4</content>
|
||||
<published>2000-01-04T00:00:00Z</published>
|
||||
<updated>2000-01-04T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:6d4c7964-43e1-11e7-92bd-4fed65d89793</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/5"/>
|
||||
<title>Article title 5</title>
|
||||
<content>Article content 5</content>
|
||||
<published>2000-01-05T00:00:00Z</published>
|
||||
<updated>2000-01-05T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:b0b9698c-43e6-11e7-85b4-53a6b351844b</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/6"/>
|
||||
<title>Article title 6</title>
|
||||
<content>Article content 6</content>
|
||||
<published>2000-01-06T00:00:00Z</published>
|
||||
<updated>2000-01-06T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:7017ed6a-43ee-11e7-b2db-09225eb114d1</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/7"/>
|
||||
<title>Article title 7</title>
|
||||
<content>Article content 7</content>
|
||||
<published>2000-01-07T00:00:00Z</published>
|
||||
<updated>2000-01-07T00:00:00Z</updated>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>urn:uuid:845a98fe-43ee-11e7-a252-cde4cbf755f3</id>
|
||||
<link rel="alternate" type="text/html" href="http://example.com/8"/>
|
||||
<title>Article title 8</title>
|
||||
<content>Article content 8</content>
|
||||
<published>2000-01-08T00:00:00Z</published>
|
||||
<updated>2000-01-08T00:00:00Z</updated>
|
||||
</entry>
|
||||
</feed>
|
||||
MESSAGE_BODY
|
||||
];
|
Loading…
Reference in a new issue