clear(); self::$DI['app']['session']->set('usr_id', self::$DI['user']->get_id()); self::$feed_1_private = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], self::$feed_1_private_title, self::$feed_1_private_subtitle); self::$feed_1_private->set_public(false); self::$feed_1_private->set_icon(__DIR__ . '/../../../../../files/logocoll.gif'); self::$feed_2_private = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], self::$feed_2_private_title, self::$feed_2_private_subtitle); self::$feed_2_private->set_public(false); self::$feed_3_public = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], self::$feed_3_public_title, self::$feed_3_public_subtitle); self::$feed_3_public->set_public(true); self::$feed_3_public->set_icon(__DIR__ . '/../../../../../files/logocoll.gif'); self::$feed_4_public = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], self::$feed_4_public_title, self::$feed_4_public_subtitle); self::$feed_4_public->set_public(true); $publishers = self::$feed_4_public->get_publishers(); $publisher = array_shift($publishers); self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') ->disableOriginalConstructor() ->getMock(); self::$DI['app']['notification.deliverer']->expects($this->atLeastOnce()) ->method('deliver') ->with($this->isInstanceOf('Alchemy\Phrasea\Notification\Mail\MailInfoNewPublication'), $this->equalTo(null)); for ($i = 1; $i != 15; $i++) { $entry = \Feed_Entry_Adapter::create(self::$DI['app'], self::$feed_4_public, $publisher, 'titre entry', 'soustitre entry', 'Jean-Marie Biggaro', 'author@example.com'); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_1']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_6']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_7']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_8']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_9']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_10']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_1']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_13']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_15']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_16']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_19']); $entry = \Feed_Entry_Adapter::create(self::$DI['app'], self::$feed_1_private, $publisher, 'titre entry', 'soustitre entry', 'Jean-Marie Biggaro', 'author@example.com'); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_1']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_6']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_7']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_8']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_9']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_10']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_1']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_13']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_15']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_16']); $item = \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], $entry, self::$DI['record_19']); self::$feed_4_entries[] = $entry; } self::$public_feeds = \Feed_Collection::load_public_feeds(self::$DI['app']); self::$private_feeds = \Feed_Collection::load_all(self::$DI['app'], self::$DI['user']); self::$DI['app']['session']->clear(); self::$initialized = true; } self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') ->disableOriginalConstructor() ->getMock(); self::$DI['app']['notification.deliverer']->expects($this->atLeastOnce()) ->method('deliver') ->with($this->isInstanceOf('Alchemy\Phrasea\Notification\Mail\MailInfoNewPublication'), $this->equalTo(null)); self::$feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], 'title', 'subtitle'); self::$publisher = \Feed_Publisher_Adapter::getPublisher(self::$DI['app']['phraseanet.appbox'], self::$feed, self::$DI['user']); self::$entry = \Feed_Entry_Adapter::create(self::$DI['app'], self::$feed, self::$publisher, 'title_entry', 'subtitle', 'hello', "test@mail.com"); \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], self::$entry, self::$DI['record_1']); \Feed_Entry_Item::create(self::$DI['app']['phraseanet.appbox'], self::$entry, self::$DI['record_2']); self::$feed->set_public(true); } public function tearDown() { if (self::$publisher instanceof \Feed_Publisher_Adapter) { self::$publisher->delete(); } if (self::$entry instanceof \Feed_Entry_Adapter) { self::$entry->delete(); } if (self::$feed instanceof \Feed_Adapter) { self::$feed->delete(); } parent::tearDown(); } public static function setUpBeforeClass() { parent::setUpBeforeClass(); $application = new Application('test'); } public static function tearDownAfterClass() { self::$feed_1_private->delete(); self::$feed_2_private->delete(); self::$feed_3_public->delete(); self::$feed_4_public->delete(); parent::tearDownAfterClass(); } public function testPublicFeedAggregated() { self::$public_feeds->get_aggregate(); self::$DI['client']->request('GET', '/feeds/aggregated/atom/'); $response = self::$DI['client']->getResponse(); $this->evaluateResponse200($response); $this->evaluateGoodXML($response); $this->evaluateAtom($response); } protected function evaluateAtom(Response $response) { $dom_doc = new \DOMDocument(); $dom_doc->preserveWhiteSpace = false; $dom_doc->loadXML($response->getContent()); $xpath = new \DOMXPath($dom_doc); $xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom'); $this->assertEquals(1, $xpath->query('/atom:feed/atom:title')->length); $this->assertEquals(1, $xpath->query('/atom:feed/atom:updated')->length); $this->assertEquals(1, $xpath->query('/atom:feed/atom:link[@rel="self"]')->length); $this->assertEquals(1, $xpath->query('/atom:feed/atom:id')->length); $this->assertEquals(1, $xpath->query('/atom:feed/atom:generator')->length); $this->assertEquals(1, $xpath->query('/atom:feed/atom:subtitle')->length); } protected function evaluateGoodXML(Response $response) { $dom_doc = new \DOMDocument(); $dom_doc->loadXML($response->getContent()); $this->assertInstanceOf('DOMDocument', $dom_doc); $this->assertEquals($dom_doc->saveXML(), $response->getContent()); } protected function evaluateResponse200(Response $response) { $this->assertEquals(200, $response->getStatusCode(), 'Test status code '); $this->assertEquals('UTF-8', $response->getCharset(), 'Test charset response'); } public function testPublicFeed() { $this->authenticate(self::$DI['app']); $link = self::$feed_3_public->get_user_link(self::$DI['app']['phraseanet.registry'], self::$DI['user'], \Feed_Adapter::FORMAT_ATOM)->get_href(); $link = str_replace(self::$DI['app']['phraseanet.registry']->get('GV_ServerName') . 'feeds/', '/', $link); $this->logout(self::$DI['app']); self::$DI['client']->request('GET', "/feeds" . $link); $response = self::$DI['client']->getResponse(); $this->evaluateResponse200($response); $this->evaluateGoodXML($response); $this->evaluateAtom($response); } public function testUserFeedAggregated() { $this->authenticate(self::$DI['app']); $link = self::$private_feeds->get_aggregate()->get_user_link(self::$DI['app']['phraseanet.registry'], self::$DI['user'], \Feed_Adapter::FORMAT_ATOM)->get_href(); $link = str_replace(self::$DI['app']['phraseanet.registry']->get('GV_ServerName') . 'feeds/', '/', $link); $this->logout(self::$DI['app']); self::$DI['client']->request('GET', "/feeds" . $link); $response = self::$DI['client']->getResponse(); $this->evaluateResponse200($response); $this->evaluateGoodXML($response); $this->evaluateAtom($response); } public function testUserFeed() { $this->authenticate(self::$DI['app']); $link = self::$feed_1_private->get_user_link(self::$DI['app']['phraseanet.registry'], self::$DI['user'], \Feed_Adapter::FORMAT_ATOM)->get_href(); $link = str_replace(self::$DI['app']['phraseanet.registry']->get('GV_ServerName') . 'feeds/', '/', $link); $this->logout(self::$DI['app']); self::$DI['client']->request('GET', "/feeds" . $link); $response = self::$DI['client']->getResponse(); $this->evaluateResponse200($response); $this->evaluateGoodXML($response); $this->evaluateAtom($response); } public function testGetFeedFormat() { $feeds = \Feed_Collection::load_public_feeds(self::$DI['app']); $all_feeds = $feeds->get_feeds(); $feed = array_shift($all_feeds); $crawler = self::$DI['client']->request("GET", "/feeds/feed/" . $feed->get_id() . "/rss/"); $this->assertEquals("application/rss+xml", self::$DI['client']->getResponse()->headers->get("content-type")); $xml = self::$DI['client']->getResponse()->getContent(); $this->verifyXML($xml); $this->verifyRSS($feed, $xml); $crawler = self::$DI['client']->request("GET", "/feeds/feed/" . $feed->get_id() . "/atom/"); $this->assertEquals("application/atom+xml", self::$DI['client']->getResponse()->headers->get("content-type")); $xml = self::$DI['client']->getResponse()->getContent(); $this->verifyXML($xml); $this->verifyATOM($feed, $xml); } public function testCooliris() { $crawler = self::$DI['client']->request("GET", "/feeds/cooliris/"); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); $this->assertEquals("application/rss+xml", self::$DI['client']->getResponse()->headers->get("content-type")); $xml = self::$DI['client']->getResponse()->getContent(); $this->verifyXML($xml); } public function testAggregatedRss() { $feeds = \Feed_Collection::load_public_feeds(self::$DI['app']); $all_feeds = $feeds->get_feeds(); foreach ($all_feeds as $feed) { $this->assertTrue($feed->is_public()); } $crawler = self::$DI['client']->request("GET", "/feeds/aggregated/rss/"); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); $this->assertEquals("application/rss+xml", self::$DI['client']->getResponse()->headers->get("content-type")); $xml = self::$DI['client']->getResponse()->getContent(); $this->verifyXML($xml); } public function testAggregatedAtom() { $feeds = \Feed_Collection::load_public_feeds(self::$DI['app']); $all_feeds = $feeds->get_feeds(); foreach ($all_feeds as $feed) { $this->assertTrue($feed->is_public()); } $crawler = self::$DI['client']->request("GET", "/feeds/aggregated/atom/"); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); $this->assertEquals("application/atom+xml", self::$DI['client']->getResponse()->headers->get("content-type")); $xml = self::$DI['client']->getResponse()->getContent(); $this->verifyXML($xml); } public function testUnknowFeedId() { self::$DI['client']->request("GET", "/feeds/feed/0/rss/"); $this->assertEquals(404, self::$DI['client']->getResponse()->getStatusCode()); } public function testUnknowFeedId2() { self::$DI['client']->request("GET", "/feeds/feed/titi/"); $this->assertNotFoundResponse(self::$DI['client']->getResponse()); } public function testGetFeedId() { $feeds = \Feed_Collection::load_public_feeds(self::$DI['app']); $all_feeds = $feeds->get_feeds(); $feed = array_shift($all_feeds); $crawler = self::$DI['client']->request("GET", "/feeds/feed/" . $feed->get_id() . "/rss/"); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); $xml = self::$DI['client']->getResponse()->getContent(); $this->verifyXML($xml); $this->verifyRSS($feed, $xml); $crawler = self::$DI['client']->request("GET", "/feeds/feed/" . $feed->get_id() . "/atom/"); $this->assertTrue(self::$DI['client']->getResponse()->isOk()); $xml = self::$DI['client']->getResponse()->getContent(); $this->verifyATOM($feed, $xml); } public function testPrivateFeedAccess() { $private_feed = \Feed_Adapter::create(self::$DI['app'], self::$DI['user'], 'title', 'subtitle'); $private_feed->set_public(false); self::$DI['client']->request("GET", "/feeds/feed/" . $private_feed->get_id() . "/rss/"); $this->assertFalse(self::$DI['client']->getResponse()->isOk()); $this->assertEquals(403, self::$DI['client']->getResponse()->getStatusCode()); $private_feed->delete(); } public function verifyXML($xml) { /** * XML is not verified due to Validator Service bug */ return; try { $validator = new W3CFeedRawValidator($xml); $response = $validator->validate(); $this->assertTrue($response->isValid(), $xml . "\n" . $response); } catch (W3CFeedValidatorException $e) { print "\nCould not use W3C FEED VALIDATOR API : " . $e->getMessage() . "\n"; } } function verifyRSS(\Feed_Adapter $feed, $xml_string) { $dom_doc = new \DOMDocument(); $dom_doc->loadXML($xml_string); $xpath = new \DOMXPath($dom_doc); $xpath->registerNamespace("media", "http://search.yahoo.com/mrss/"); $xpath->registerNamespace("atom", "http://www.w3.org/2005/Atom"); $xpath->registerNamespace("dc", "http://purl.org/dc/elements/1.1/"); $this->checkRSSRootNode($xpath, $feed); $this->checkRSSEntryNode($xpath, $feed); } function checkRSSRootNode(\DOMXPath $xpath, \Feed_Adapter $feed) { $channel = $xpath->query("/rss/channel"); foreach ($channel->item(0)->childNodes as $child) { if ($child->nodeType !== XML_TEXT_NODE) { switch ($child->nodeName) { case 'title': $this->assertEquals($feed->get_title(), $child->nodeValue); break; case 'dc:title': $this->assertEquals($feed->get_title(), $child->nodeValue); break; case 'description': $this->assertEquals($feed->get_subtitle(), $child->nodeValue); break; case 'link': $this->assertEquals($feed->get_homepage_link(self::$DI['app']['phraseanet.registry'], \Feed_Adapter::FORMAT_RSS, 1)->get_href(), $child->nodeValue); break; case 'pubDate': $this->assertTrue(new \DateTime() >= new \DateTime($child->nodeValue)); break; case 'generator': $this->assertEquals("Phraseanet", $child->nodeValue); break; case 'docs': $this->assertEquals("http://blogs.law.harvard.edu/tech/rss", $child->nodeValue); break; case 'atom:link': foreach ($child->attributes as $attribute) { if ($attribute->name == "href") { $this->assertEquals($feed->get_homepage_link(self::$DI['app']['phraseanet.registry'], \Feed_Adapter::FORMAT_RSS, 1)->get_href(), $attribute->value); break; } } break; } } } } function checkRSSEntryNode(\DOMXPath $xpath, \Feed_Adapter $feed) { $list_entries = $xpath->query("/rss/channel/item"); $count = 0; $offset_start = 0; $n_entries = 20; $collection = $feed->get_entries($offset_start, $n_entries); $entries = $collection->get_entries(); foreach ($list_entries as $node) { if (sizeof($entries) == 0) { $offset_start = ($offset_start++) * $n_entries; $collection = $feed->get_entries($offset_start, $n_entries); $entries = $collection->get_entries(); if (sizeof($entries) == 0) //no more break; } $feed_entry = array_shift($entries); switch ($node->nodeName) { case 'title': $this->assertEquals($feed_entry->get_title(), $node->nodeValue); break; case 'description': $this->assertEquals($feed_entry->get_subtitle(), $node->nodeValue); break; case 'author': $author = sprintf( '%s (%s)' , $feed_entry->get_author_email() , $feed_entry->get_author_name() ); $this->assertEquals($author, $node->nodeValue); break; case 'pubDate': $this->assertEquals($feed_entry->get_created_on()->format(DATE_RFC2822), $node->nodeValue); break; case 'guid': $this->assertEquals($feed_entry->get_link()->get_href(), $node->nodeValue); break; case 'link': $this->assertEquals($feed_entry->get_link()->get_href(), $node->nodeValue); break; } $count++; $this->checkRSSEntryItemsNode($xpath, $feed_entry, $count); } $this->assertEquals($feed->get_count_total_entries(), $count); } function checkRSSEntryItemsNode(\DOMXPath $xpath, \Feed_Entry_Adapter $entry, $count) { $content = $entry->get_content(); $available_medium = array('image', 'audio', 'video'); array_walk($content, $this->removeBadItems($content, $available_medium)); $media_group = $xpath->query("/rss/channel/item[" . $count . "]/media:group"); $this->assertEquals(sizeof($content), $media_group->length, sizeof($content)." != ".$media_group->length); foreach ($media_group as $media) { $entry_item = array_shift($content); $this->verifyMediaItem($entry_item, $media); } } public function verifyMediaItem(\Feed_Entry_Item $item, \DOMNode $node) { foreach ($node->childNodes as $node) { if ($node->nodeType !== XML_TEXT_NODE) { switch ($node->nodeName) { case 'media:content' : $this->checkMediaContentAttributes($item, $node); break; case 'media:thumbnail': default : $this->checkOptionnalMediaGroupNode($node, $item); break; } } } } public function parseAttributes(\DOMNode $node) { $current_attributes = array(); foreach ($node->attributes as $attribute) { $current_attributes[$attribute->name] = $attribute->value; } return $current_attributes; } public function checkMediaContentAttributes(\Feed_Entry_Item $entry_item, \DOMNode $node) { $current_attributes = $this->parseAttributes($node); $is_thumbnail = false; $record = $entry_item->get_record(); if (false !== strpos($current_attributes["url"], 'preview')) { $ressource = $record->get_subdef('preview'); } else { $ressource = $record->get_thumbnail(); $is_thumbnail = true; } $permalink = $ressource->get_permalink(); foreach ($current_attributes as $attribute => $value) { switch ($attribute) { case "url": $this->assertEquals($permalink->get_url(), $value); break; case "fileSize": $this->assertEquals($ressource->get_size(), $value); break; case "type": $this->assertEquals($ressource->get_mime(), $value); break; case "medium": $this->assertEquals(strtolower($record->get_type()), $value); break; case "isDefault": !$is_thumbnail ? $this->assertEquals("true", $value) : $this->assertEquals("false", $value); break; case "expression": $this->assertEquals("full", $value); break; case "bitrate": $this->assertEquals($value); break; case "height": $this->assertEquals($ressource->get_height(), $value); break; case "width": $this->assertEquals($ressource->get_width(), $value); break; case "duration" : $this->assertEquals($record->get_duration(), $value); break; case "framerate": case "samplingrate": case "channels": case "lang": break; default: $this->fail($attribute . " is not valid"); break; } } } public function checkOptionnalMediaGroupNode(\DOMNode $node, \Feed_Entry_Item $entry_item) { $fields = array( 'title' => array( 'dc_field' => \databox_Field_DCESAbstract::Title, 'media_field' => array( 'name' => 'media:title', 'attributes' => array( 'type' => 'plain' ) ), 'separator' => ' ' ) , 'description' => array( 'dc_field' => \databox_Field_DCESAbstract::Description, 'media_field' => array( 'name' => 'media:description', 'attributes' => array() ), 'separator' => ' ' ) , 'contributor' => array( 'dc_field' => \databox_Field_DCESAbstract::Contributor, 'media_field' => array( 'name' => 'media:credit', 'attributes' => array( 'role' => 'contributor', 'scheme' => 'urn:ebu' ) ), 'separator' => ' ' ) , 'director' => array( 'dc_field' => \databox_Field_DCESAbstract::Creator, 'media_field' => array( 'name' => 'media:credit', 'attributes' => array( 'role' => 'director', 'scheme' => 'urn:ebu' ) ), 'separator' => ' ' ) , 'publisher' => array( 'dc_field' => \databox_Field_DCESAbstract::Publisher, 'media_field' => array( 'name' => 'media:credit', 'attributes' => array( 'role' => 'publisher', 'scheme' => 'urn:ebu' ) ), 'separator' => ' ' ) , 'rights' => array( 'dc_field' => \databox_Field_DCESAbstract::Rights, 'media_field' => array( 'name' => 'media:copyright', 'attributes' => array() ), 'separator' => ' ' ) , 'keywords' => array( 'dc_field' => \databox_Field_DCESAbstract::Subject, 'media_field' => array( 'name' => 'media:keywords', 'attributes' => array() ), 'separator' => ', ' ) ); foreach ($fields as $key_field => $field) { $role = true; if (isset($field["media_field"]['attributes']['role'])) { $role = false; foreach ($node->attributes as $attr) { if ($attr->name == 'role') { $role = $attr->value == $field["media_field"]['attributes']['role']; break; } } } if ($field["media_field"]["name"] == $node->nodeName && $role != false) { if ($p4field = $entry_item->get_record()->get_caption()->get_dc_field($field["dc_field"])) { $this->assertEquals($p4field->get_serialized_values($field["separator"]), $node->nodeValue, sprintf('Asserting good value for DC %s', $field["dc_field"])); if (sizeof($field["media_field"]["attributes"]) > 0) { foreach ($node->attributes as $attribute) { $this->assertTrue(array_key_exists($attribute->name, $field["media_field"]["attributes"]), "Checkin attribute " . $attribute->name . " for " . $field['media_field']['name']); $this->assertEquals($attribute->value, $field["media_field"]["attributes"][$attribute->name], "Checkin attribute " . $attribute->name . " for " . $field['media_field']['name']); } } } else { $this->fail("Missing media:entry"); } break; } } } public function removeBadItems(Array &$item_entries, Array $available_medium) { $remove = function($entry_item, $key) use (&$item_entries, $available_medium) { $preview_sd = $entry_item->get_record()->get_subdef('preview'); $url_preview = $preview_sd->get_permalink(); $thumbnail_sd = $entry_item->get_record()->get_thumbnail(); $url_thumb = $thumbnail_sd->get_permalink(); if (!in_array(strtolower($entry_item->get_record()->get_type()), $available_medium)) { unset($item_entries[$key]); //remove } if (!$url_thumb || !$url_preview) { unset($item_entries[$key]); //remove } }; return $remove; } public function verifyATOM(\Feed_Adapter $feed, $xml_string) { $this->verifyXML($xml_string); $dom_doc = new \DOMDocument(); $dom_doc->loadXML($xml_string); $xpath = new \DOMXPath($dom_doc); $xpath->registerNamespace("media", "http://search.yahoo.com/mrss/"); $xpath->registerNamespace("Atom", "http://www.w3.org/2005/Atom"); $this->checkATOMRootNode($dom_doc, $xpath, $feed); } public function checkATOMRootNode(\DOMDocument $dom_doc, \DOMXPath $xpath, \Feed_Adapter $feed) { $ids = $xpath->query('/Atom:feed/Atom:id'); $this->assertEquals($feed->get_homepage_link(self::$DI['app']['phraseanet.registry'], \Feed_Adapter::FORMAT_ATOM, 1)->get_href(), $ids->item(0)->nodeValue); $titles = $xpath->query('/Atom:feed/Atom:title'); $this->assertEquals($feed->get_title(), $titles->item(0)->nodeValue); $subtitles = $xpath->query('/Atom:feed/Atom:subtitle'); if ($subtitles->length > 0) $this->assertEquals($feed->get_subtitle(), $subtitles->item(0)->nodeValue); $updateds = $xpath->query('/Atom:feed/Atom:updated'); $this->assertTrue(new \DateTime() >= new \DateTime($updateds->item(0)->nodeValue)); $entries_item = $xpath->query('/Atom:feed/Atom:entry'); $count = 0; $offset_start = 0; $n_entries = 20; $collection = $feed->get_entries($offset_start, $n_entries); $entries = $collection->get_entries(); foreach ($entries_item as $entry) { if (sizeof($entries) == 0) { $offset_start = ($offset_start++) * $n_entries; $collection = $feed->get_entries($offset_start, $n_entries); $entries = $collection->get_entries(); if (sizeof($entries) == 0) //no more break; } $feed_entry = array_shift($entries); $this->checkATOMEntryNode($entry, $xpath, $feed, $feed_entry); $count++; } $this->assertEquals($feed->get_count_total_entries(), $count); } public function checkATOMEntryNode(\DOMNode $node, \DOMXPath $xpath, \Feed_Adapter $feed, \Feed_Entry_Adapter $entry) { foreach ($node->childNodes as $child) { if ($child->nodeType !== XML_TEXT_NODE) { switch ($child->nodeName) { case 'id': $this->assertEquals(sprintf('%sentry/%d/', $feed->get_homepage_link(self::$DI['app']['phraseanet.registry'], \Feed_Adapter::FORMAT_ATOM, 1)->get_href(), $entry->get_id()), $child->nodeValue); break; case 'link': foreach ($child->attributes as $attribute) { if ($attribute->name == "href") { $this->assertEquals(sprintf('%sentry/%d/', $feed->get_homepage_link(self::$DI['app']['phraseanet.registry'], \Feed_Adapter::FORMAT_ATOM, 1)->get_href(), $entry->get_id()), $attribute->value); break; } } break; case 'updated': $this->assertEquals($entry->get_updated_on()->format(DATE_ATOM), $child->nodeValue); break; case 'published': $this->assertEquals($entry->get_created_on()->format(DATE_ATOM), $child->nodeValue); break; case 'title': $this->assertEquals($entry->get_title(), $child->nodeValue); break; case 'content': $this->assertEquals($entry->get_subtitle(), $child->nodeValue); break; case 'author': foreach ($node->childNodes as $child) { if ($child->nodeType !== XML_TEXT_NODE && $child->nodeName == "email") $this->assertEquals($entry->get_author_email(), $child->nodeValue); if ($child->nodeType !== XML_TEXT_NODE && $child->nodeName == "name") $this->assertEquals($entry->get_author_name(), $child->nodeValue); } break; } } } $content = $entry->get_content(); $available_medium = array('image', 'audio', 'video'); array_walk($content, $this->removeBadItems($content, $available_medium)); $media_group = $xpath->query("/Atom:feed/Atom:entry[0]/media:group"); if ($media_group->length > 0) { foreach ($media_group as $media) { $entry_item = array_shift($content); if ($entry_item instanceof \Feed_Entry_Item) { $this->verifyMediaItem($entry_item, $media); } } } } }