Browse Source

finishes the refactor!

pull/38/head
Aaron Parecki 4 years ago
parent
commit
78e3e16592
No known key found for this signature in database GPG Key ID: 276C2817346D6056
8 changed files with 267 additions and 193 deletions
  1. +54
    -1
      README.md
  2. +5
    -5
      composer.lock
  3. +19
    -132
      controllers/Parse.php
  4. +7
    -2
      lib/XRay/Fetcher.php
  5. +132
    -0
      lib/XRay/Formats/HTML.php
  6. +22
    -23
      lib/XRay/Formats/Mf2.php
  7. +2
    -5
      lib/XRay/Parser.php
  8. +26
    -25
      tests/ParseTest.php

+ 54
- 1
README.md View File

@ -22,7 +22,53 @@ The contents of the URL is checked in the following order:
* h-recipe
* h-product
## Parse API
## Library
XRay can be used as a library in your PHP project. The easiest way to install it and its dependencies is via composer.
```
composer require p3k/xray
```
Basic usage:
```php
$xray = new p3k\XRay();
$parsed = $xray->parse('https://aaronparecki.com/2017/04/28/9/');
```
If you already have an HTML or JSON document you want to parse, you can pass it as a string in the second parameter.
```php
$xray = new p3k\XRay();
$html = '<html>....</html>';
$parsed = $xray->parse('https://aaronparecki.com/2017/04/28/9/', $html);
```
In both cases, you can add an additional parameter to configure various options of how XRay will behave. Below is a list of the options.
* `timeout` - The timeout in seconds to wait for any HTTP requests
* `max_redirects` - The maximum number of redirects to follow
* `include_original` - Will also return the full document fetched
* `target` - Specify a target URL, and XRay will first check if that URL is on the page, and only if it is, will continue to parse the page. This is useful when you're using XRay to verify an incoming webmention.
Additionally, the following parameters are supported when making requests that use the Twitter or GitHub API. See the authentication section below for details.
```php
$xray = new p3k\XRay();
$parsed = $xray->parse('https://aaronparecki.com/2017/04/28/9/', [
'timeout' => 30
]);
$parsed = $xray->parse('https://aaronparecki.com/2017/04/28/9/', $html, [
'target' => 'http://example.com/'
]);
```
## API
XRay can also be used as an API to provide its parsing capabilities over an HTTP service.
To parse a page and return structured data for the contents of the page, simply pass a url to the parse route.
@ -84,6 +130,13 @@ You should only send Twitter credentials when the URL you are trying to parse is
* twitter_access_token_secret - Your Twitter secret access token
### GitHub Authentication
XRay uses the GitHub API to fetch GitHub URLs, which provides higher rate limits when used with authentication. You can pass a GitHub access token along with the request and XRay will use it when making requests to the API.
* github_access_token - A GitHub access token
### Error Response
```json

+ 5
- 5
composer.lock View File

@ -256,16 +256,16 @@
},
{
"name": "p3k/http",
"version": "0.1.4",
"version": "0.1.5",
"source": {
"type": "git",
"url": "https://github.com/aaronpk/p3k-http.git",
"reference": "136aac6f7ecd6d6e16e8ff9286b43110680c49ab"
"reference": "3740fe135e6d58457d7528e7c05a67b68e020a79"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aaronpk/p3k-http/zipball/136aac6f7ecd6d6e16e8ff9286b43110680c49ab",
"reference": "136aac6f7ecd6d6e16e8ff9286b43110680c49ab",
"url": "https://api.github.com/repos/aaronpk/p3k-http/zipball/3740fe135e6d58457d7528e7c05a67b68e020a79",
"reference": "3740fe135e6d58457d7528e7c05a67b68e020a79",
"shasum": ""
},
"require": {
@ -290,7 +290,7 @@
],
"description": "A simple wrapper API around the PHP curl functions",
"homepage": "https://github.com/aaronpk/p3k-http",
"time": "2017-04-28T19:46:12+00:00"
"time": "2017-04-29T17:43:29+00:00"
},
{
"name": "p3k/timezone",

+ 19
- 132
controllers/Parse.php View File

@ -41,10 +41,6 @@ class Parse {
return $response;
}
private static function toHtmlEntities($input) {
return mb_convert_encoding($input, 'HTML-ENTITIES', mb_detect_encoding($input));
}
public function parse(Request $request, Response $response) {
$opts = [];
@ -57,6 +53,10 @@ class Parse {
$opts['max_redirects'] = (int)$request->get('max_redirects');
}
if($request->get('target')) {
$opts['target'] = $request->get('target');
}
if($request->get('pretty')) {
$this->_pretty = true;
}
@ -105,136 +105,23 @@ class Parse {
if(isset($parsed['code']))
$result['code'] = $parsed['code'];
$data = [
'data' => $parsed['data'],
'url' => $result['url'],
'code' => $result['code']
];
if($request->get('include_original') && isset($parsed['original']))
$data['original'] = $parsed['original'];
return $this->respond($response, 200, $data);
// attempt to parse the page as HTML
$doc = new DOMDocument();
@$doc->loadHTML(self::toHtmlEntities($result['body']));
if(!$doc) {
return $this->respond($response, 200, [
'error' => 'invalid_content',
'error_description' => 'The document could not be parsed as HTML'
]);
}
$xpath = new DOMXPath($doc);
// Check for meta http equiv and replace the status code if present
foreach($xpath->query('//meta[translate(@http-equiv,\'STATUS\',\'status\')=\'status\']') as $el) {
$equivStatus = ''.$el->getAttribute('content');
if($equivStatus && is_string($equivStatus)) {
if(preg_match('/^(\d+)/', $equivStatus, $match)) {
$result['code'] = (int)$match[1];
}
}
}
// If a target parameter was provided, make sure a link to it exists on the page
if($target=$request->get('target')) {
$found = [];
if($target) {
self::xPathFindNodeWithAttribute($xpath, 'a', 'href', function($u) use($target, &$found){
if($u == $target) {
$found[$u] = null;
}
});
self::xPathFindNodeWithAttribute($xpath, 'img', 'src', function($u) use($target, &$found){
if($u == $target) {
$found[$u] = null;
}
});
self::xPathFindNodeWithAttribute($xpath, 'video', 'src', function($u) use($target, &$found){
if($u == $target) {
$found[$u] = null;
}
});
self::xPathFindNodeWithAttribute($xpath, 'audio', 'src', function($u) use($target, &$found){
if($u == $target) {
$found[$u] = null;
}
});
}
if(!$found) {
return $this->respond($response, 200, [
'error' => 'no_link_found',
'error_description' => 'The source document does not have a link to the target URL',
'url' => $result['url'],
'code' => $result['code'],
]);
}
}
// If the URL has a fragment ID, find the DOM starting at that node and parse it instead
$html = $result['body'];
$fragment = parse_url($url, PHP_URL_FRAGMENT);
if($fragment) {
$fragElement = self::xPathGetElementById($xpath, $fragment);
if($fragElement) {
$html = $doc->saveHTML($fragElement);
$foundFragment = true;
} else {
$foundFragment = false;
}
}
// Now start pulling in the data from the page. Start by looking for microformats2
$mf2 = mf2\Parse($html, $result['url']);
if($mf2 && count($mf2['items']) > 0) {
$data = Formats\Mf2::parse($mf2, $result['url'], $this->http);
if($data) {
if($fragment) {
$data['info'] = [
'found_fragment' => $foundFragment
];
}
if($request->get('include_original'))
$data['original'] = $html;
$data['url'] = $result['url']; // this will be the effective URL after following redirects
$data['code'] = $result['code'];
return $this->respond($response, 200, $data);
}
}
// TODO: look for other content like OEmbed or other known services later
return $this->respond($response, 200, [
'data' => [
'type' => 'unknown',
],
'url' => $result['url'],
'code' => $result['code']
]);
}
private static function xPathFindNodeWithAttribute($xpath, $node, $attr, $callback) {
foreach($xpath->query('//'.$node.'[@'.$attr.']') as $el) {
$v = $el->getAttribute($attr);
$callback($v);
}
}
if(!empty($parsed['error'])) {
$error_code = isset($parsed['error_code']) ? $parsed['error_code'] : 200;
unset($parsed['error_code']);
return $this->respond($response, $error_code, $parsed);
} else {
$data = [
'data' => $parsed['data'],
'url' => $result['url'],
'code' => $result['code']
];
if(isset($parsed['info']))
$data['info'] = $parsed['info'];
if($request->get('include_original') && isset($parsed['original']))
$data['original'] = $parsed['original'];
private static function xPathGetElementById($xpath, $id) {
$element = null;
foreach($xpath->query("//*[@id='$id']") as $el) {
$element = $el;
return $this->respond($response, 200, $data);
}
return $element;
}
}

+ 7
- 2
lib/XRay/Fetcher.php View File

@ -78,7 +78,8 @@ class Fetcher {
if($result['code'] == 410) {
// 410 Gone responses are valid and should not return an error
return $this->respond($response, 200, [
'TODO' => [
'data' => [
'type' => 'unknown'
],
'url' => $result['url'],
'code' => $result['code']
@ -111,6 +112,11 @@ class Fetcher {
];
}
// If the original URL had a fragment, include it in the final URL
if(($fragment=parse_url($url, PHP_URL_FRAGMENT)) && !parse_url($result['url'], PHP_URL_FRAGMENT)) {
$result['url'] .= '#'.$fragment;
}
return [
'url' => $result['url'],
'body' => $result['body'],
@ -127,7 +133,6 @@ class Fetcher {
}
if(count($creds) < 4) {
print_r(debug_backtrace()[1]);
return [
'error_code' => 400,
'error' => 'missing_parameters',

+ 132
- 0
lib/XRay/Formats/HTML.php View File

@ -0,0 +1,132 @@
<?php
namespace p3k\XRay\Formats;
use HTMLPurifier, HTMLPurifier_Config;
use DOMDocument, DOMXPath;
use p3k\XRay\Formats;
class HTML extends Format {
public static function matches_host($url) { return true; }
public static function matches($url) { return true; }
public static function parse($http, $html, $url, $opts=[]) {
$result = [
'data' => [
'type' => 'unknown',
],
'url' => $url,
];
// attempt to parse the page as HTML
$doc = new DOMDocument();
@$doc->loadHTML(self::toHtmlEntities($html));
if(!$doc) {
return [
'error' => 'invalid_content',
'error_description' => 'The document could not be parsed as HTML'
];
}
$xpath = new DOMXPath($doc);
// Check for meta http equiv and replace the status code if present
foreach($xpath->query('//meta[translate(@http-equiv,\'STATUS\',\'status\')=\'status\']') as $el) {
$equivStatus = ''.$el->getAttribute('content');
if($equivStatus && is_string($equivStatus)) {
if(preg_match('/^(\d+)/', $equivStatus, $match)) {
$result['code'] = (int)$match[1];
}
}
}
// If a target parameter was provided, make sure a link to it exists on the page
if(isset($opts['target'])) {
$target = $opts['target'];
$found = [];
if($target) {
self::xPathFindNodeWithAttribute($xpath, 'a', 'href', function($u) use($target, &$found){
if($u == $target) {
$found[$u] = null;
}
});
self::xPathFindNodeWithAttribute($xpath, 'img', 'src', function($u) use($target, &$found){
if($u == $target) {
$found[$u] = null;
}
});
self::xPathFindNodeWithAttribute($xpath, 'video', 'src', function($u) use($target, &$found){
if($u == $target) {
$found[$u] = null;
}
});
self::xPathFindNodeWithAttribute($xpath, 'audio', 'src', function($u) use($target, &$found){
if($u == $target) {
$found[$u] = null;
}
});
}
if(!$found) {
return [
'error' => 'no_link_found',
'error_description' => 'The source document does not have a link to the target URL',
'code' => isset($result['code']) ? $result['code'] : 200,
'url' => $url
];
}
}
// If the URL has a fragment ID, find the DOM starting at that node and parse it instead
$fragment = parse_url($url, PHP_URL_FRAGMENT);
if($fragment) {
$fragElement = self::xPathGetElementById($xpath, $fragment);
if($fragElement) {
$html = $doc->saveHTML($fragElement);
$foundFragment = true;
} else {
$foundFragment = false;
}
}
// Now start pulling in the data from the page. Start by looking for microformats2
$mf2 = \mf2\Parse($html, $url);
if($mf2 && count($mf2['items']) > 0) {
$data = Formats\Mf2::parse($mf2, $url, $http);
$result = array_merge($result, $data);
if($data) {
if($fragment) {
$result['info'] = [
'found_fragment' => $foundFragment
];
}
$result['original'] = $html;
$result['url'] = $url; // this will be the effective URL after following redirects
}
}
return $result;
}
private static function toHtmlEntities($input) {
return mb_convert_encoding($input, 'HTML-ENTITIES', mb_detect_encoding($input));
}
private static function xPathFindNodeWithAttribute($xpath, $node, $attr, $callback) {
foreach($xpath->query('//'.$node.'[@'.$attr.']') as $el) {
$v = $el->getAttribute($attr);
$callback($v);
}
}
private static function xPathGetElementById($xpath, $id) {
$element = null;
foreach($xpath->query("//*[@id='$id']") as $el) {
$element = $el;
}
return $element;
}
}

+ 22
- 23
lib/XRay/Formats/Mf2.php View File

@ -2,7 +2,6 @@
namespace p3k\XRay\Formats;
use HTMLPurifier, HTMLPurifier_Config;
use Parse;
class Mf2 {
@ -14,31 +13,31 @@ class Mf2 {
if(count($mf2['items']) == 1) {
$item = $mf2['items'][0];
if(in_array('h-entry', $item['type']) || in_array('h-cite', $item['type'])) {
Parse::debug("mf2:0: Recognized $url as an h-entry it is the only item on the page");
#Parse::debug("mf2:0: Recognized $url as an h-entry it is the only item on the page");
return self::parseAsHEntry($mf2, $item, $http);
}
if(in_array('h-event', $item['type'])) {
Parse::debug("mf2:0: Recognized $url as an h-event it is the only item on the page");
#Parse::debug("mf2:0: Recognized $url as an h-event it is the only item on the page");
return self::parseAsHEvent($mf2, $item, $http);
}
if(in_array('h-review', $item['type'])) {
Parse::debug("mf2:0: Recognized $url as an h-review it is the only item on the page");
#Parse::debug("mf2:0: Recognized $url as an h-review it is the only item on the page");
return self::parseAsHReview($mf2, $item, $http);
}
if(in_array('h-recipe', $item['type'])) {
Parse::debug("mf2:0: Recognized $url as an h-recipe it is the only item on the page");
#Parse::debug("mf2:0: Recognized $url as an h-recipe it is the only item on the page");
return self::parseAsHRecipe($mf2, $item, $http);
}
if(in_array('h-product', $item['type'])) {
Parse::debug("mf2:0: Recognized $url as an h-product it is the only item on the page");
#Parse::debug("mf2:0: Recognized $url as an h-product it is the only item on the page");
return self::parseAsHProduct($mf2, $item, $http);
}
if(in_array('h-feed', $item['type'])) {
Parse::debug("mf2:0: Recognized $url as an h-feed because it is the only item on the page");
#Parse::debug("mf2:0: Recognized $url as an h-feed because it is the only item on the page");
return self::parseAsHFeed($mf2, $http);
}
if(in_array('h-card', $item['type'])) {
Parse::debug("mf2:0: Recognized $url as an h-card it is the only item on the page");
#Parse::debug("mf2:0: Recognized $url as an h-card it is the only item on the page");
return self::parseAsHCard($item, $http, $url);
}
}
@ -50,7 +49,7 @@ class Mf2 {
$urls = $item['properties']['url'];
$urls = array_map('\p3k\XRay\normalize_url', $urls);
if(in_array($url, $urls)) {
Parse::debug("mf2:1: Recognized $url as a permalink because an object on the page matched the URL of the request");
#Parse::debug("mf2:1: Recognized $url as a permalink because an object on the page matched the URL of the request");
if(in_array('h-card', $item['type'])) {
return self::parseAsHCard($item, $http, $url);
} elseif(in_array('h-entry', $item['type']) || in_array('h-cite', $item['type'])) {
@ -64,7 +63,7 @@ class Mf2 {
} elseif(in_array('h-product', $item['type'])) {
return self::parseAsHProduct($mf2, $item, $http);
} else {
Parse::debug('This object was not a recognized type.');
#Parse::debug('This object was not a recognized type.');
return false;
}
}
@ -106,7 +105,7 @@ class Mf2 {
if(count(array_filter($mf2['items'], function($item){
return in_array('h-entry', $item['type']);
})) > 1) {
Parse::debug("mf2:2: Recognized $url as an h-feed because there are more than one object on the page");
#Parse::debug("mf2:2: Recognized $url as an h-feed because there are more than one object on the page");
return self::parseAsHFeed($mf2, $http);
}
}
@ -114,7 +113,7 @@ class Mf2 {
// If the first item is an h-feed, parse as a feed
$first = $mf2['items'][0];
if(in_array('h-feed', $first['type'])) {
Parse::debug("mf2:3: Recognized $url as an h-feed because the first item is an h-feed");
#Parse::debug("mf2:3: Recognized $url as an h-feed because the first item is an h-feed");
return self::parseAsHFeed($mf2, $http);
}
@ -122,24 +121,24 @@ class Mf2 {
foreach($mf2['items'] as $item) {
// Otherwise check for a recognized h-entr* object
if(in_array('h-entry', $item['type']) || in_array('h-cite', $item['type'])) {
Parse::debug("mf2:6: $url is falling back to the first h-entry on the page");
#Parse::debug("mf2:6: $url is falling back to the first h-entry on the page");
return self::parseAsHEntry($mf2, $item, $http);
} elseif(in_array('h-event', $item['type'])) {
Parse::debug("mf2:6: $url is falling back to the first h-event on the page");
#Parse::debug("mf2:6: $url is falling back to the first h-event on the page");
return self::parseAsHEvent($mf2, $item, $http);
} elseif(in_array('h-review', $item['type'])) {
Parse::debug("mf2:6: $url is falling back to the first h-review on the page");
#Parse::debug("mf2:6: $url is falling back to the first h-review on the page");
return self::parseAsHReview($mf2, $item, $http);
} elseif(in_array('h-recipe', $item['type'])) {
Parse::debug("mf2:6: $url is falling back to the first h-recipe on the page");
#Parse::debug("mf2:6: $url is falling back to the first h-recipe on the page");
return self::parseAsHReview($mf2, $item, $http);
} elseif(in_array('h-product', $item['type'])) {
Parse::debug("mf2:6: $url is falling back to the first h-product on the page");
#Parse::debug("mf2:6: $url is falling back to the first h-product on the page");
return self::parseAsHProduct($mf2, $item, $http);
}
}
Parse::debug("mf2:E: No object at $url was recognized");
#Parse::debug("mf2:E: No object at $url was recognized");
return false;
}
@ -311,7 +310,7 @@ class Mf2 {
];
if(count($refs)) {
$response['refs'] = $refs;
$response['data']['refs'] = $refs;
}
return $response;
@ -345,7 +344,7 @@ class Mf2 {
];
if(count($refs)) {
$response['refs'] = $refs;
$response['data']['refs'] = $refs;
}
return $response;
@ -376,7 +375,7 @@ class Mf2 {
];
if(count($refs)) {
$response['refs'] = $refs;
$response['data']['refs'] = $refs;
}
return $response;
@ -403,7 +402,7 @@ class Mf2 {
];
if(count($refs)) {
$response['refs'] = $refs;
$response['data']['refs'] = $refs;
}
return $response;
@ -457,7 +456,7 @@ class Mf2 {
];
if(count($refs)) {
$response['refs'] = $refs;
$response['data']['refs'] = $refs;
}
return $response;

+ 2
- 5
lib/XRay/Parser.php View File

@ -34,11 +34,8 @@ class Parser {
return Formats\XKCD::parse($body, $url);
}
return [
'data' => [
'type' => 'unknown'
]
];
// No special parsers matched, parse for Microformats now
return Formats\HTML::parse($this->http, $body, $url, $opts);
}
}

+ 26
- 25
tests/ParseTest.php View File

@ -205,9 +205,9 @@ class ParseTest extends PHPUnit_Framework_TestCase {
$data = json_decode($body, true);
$this->assertEquals('entry', $data['data']['type']);
$this->assertEquals('http://example.com/100', $data['data']['in-reply-to'][0]);
$this->assertArrayHasKey('http://example.com/100', $data['refs']);
$this->assertEquals('Example Post', $data['refs']['http://example.com/100']['name']);
$this->assertEquals('http://example.com/100', $data['refs']['http://example.com/100']['url']);
$this->assertArrayHasKey('http://example.com/100', $data['data']['refs']);
$this->assertEquals('Example Post', $data['data']['refs']['http://example.com/100']['name']);
$this->assertEquals('http://example.com/100', $data['data']['refs']['http://example.com/100']['url']);
}
public function testPersonTagIsURL() {
@ -230,10 +230,10 @@ class ParseTest extends PHPUnit_Framework_TestCase {
$data = json_decode($body, true);
$this->assertEquals('entry', $data['data']['type']);
$this->assertEquals('http://alice.example.com/', $data['data']['category'][0]);
$this->assertArrayHasKey('http://alice.example.com/', $data['refs']);
$this->assertEquals('card', $data['refs']['http://alice.example.com/']['type']);
$this->assertEquals('http://alice.example.com/', $data['refs']['http://alice.example.com/']['url']);
$this->assertEquals('Alice', $data['refs']['http://alice.example.com/']['name']);
$this->assertArrayHasKey('http://alice.example.com/', $data['data']['refs']);
$this->assertEquals('card', $data['data']['refs']['http://alice.example.com/']['type']);
$this->assertEquals('http://alice.example.com/', $data['data']['refs']['http://alice.example.com/']['url']);
$this->assertEquals('Alice', $data['data']['refs']['http://alice.example.com/']['name']);
}
public function testSyndicationIsURL() {
@ -372,10 +372,10 @@ class ParseTest extends PHPUnit_Framework_TestCase {
$this->assertEquals($url, $data['data']['url']);
$this->assertEquals('2016-02-09T18:30', $data['data']['start']);
$this->assertEquals('2016-02-09T19:30', $data['data']['end']);
$this->assertArrayHasKey('http://source.example.com/venue', $data['refs']);
$this->assertEquals('card', $data['refs']['http://source.example.com/venue']['type']);
$this->assertEquals('http://source.example.com/venue', $data['refs']['http://source.example.com/venue']['url']);
$this->assertEquals('Venue', $data['refs']['http://source.example.com/venue']['name']);
$this->assertArrayHasKey('http://source.example.com/venue', $data['data']['refs']);
$this->assertEquals('card', $data['data']['refs']['http://source.example.com/venue']['type']);
$this->assertEquals('http://source.example.com/venue', $data['data']['refs']['http://source.example.com/venue']['url']);
$this->assertEquals('Venue', $data['data']['refs']['http://source.example.com/venue']['name']);
}
public function testMf2ReviewOfProduct() {
@ -395,10 +395,10 @@ class ParseTest extends PHPUnit_Framework_TestCase {
$this->assertContains('red', $data['data']['category']);
$this->assertContains('blue', $data['data']['category']);
$this->assertContains('http://product.example.com/', $data['data']['item']);
$this->assertArrayHasKey('http://product.example.com/', $data['refs']);
$this->assertEquals('product', $data['refs']['http://product.example.com/']['type']);
$this->assertEquals('The Reviewed Product', $data['refs']['http://product.example.com/']['name']);
$this->assertEquals('http://product.example.com/', $data['refs']['http://product.example.com/']['url']);
$this->assertArrayHasKey('http://product.example.com/', $data['data']['refs']);
$this->assertEquals('product', $data['data']['refs']['http://product.example.com/']['type']);
$this->assertEquals('The Reviewed Product', $data['data']['refs']['http://product.example.com/']['name']);
$this->assertEquals('http://product.example.com/', $data['data']['refs']['http://product.example.com/']['url']);
}
public function testMf2ReviewOfHCard() {
@ -416,10 +416,10 @@ class ParseTest extends PHPUnit_Framework_TestCase {
$this->assertEquals('5', $data['data']['best']);
$this->assertEquals('This is the full text of the review', $data['data']['content']['text']);
$this->assertContains('http://business.example.com/', $data['data']['item']);
$this->assertArrayHasKey('http://business.example.com/', $data['refs']);
$this->assertEquals('card', $data['refs']['http://business.example.com/']['type']);
$this->assertEquals('The Reviewed Business', $data['refs']['http://business.example.com/']['name']);
$this->assertEquals('http://business.example.com/', $data['refs']['http://business.example.com/']['url']);
$this->assertArrayHasKey('http://business.example.com/', $data['data']['refs']);
$this->assertEquals('card', $data['data']['refs']['http://business.example.com/']['type']);
$this->assertEquals('The Reviewed Business', $data['data']['refs']['http://business.example.com/']['name']);
$this->assertEquals('http://business.example.com/', $data['data']['refs']['http://business.example.com/']['url']);
}
public function testMf1Review() {
@ -438,10 +438,10 @@ class ParseTest extends PHPUnit_Framework_TestCase {
$this->assertEquals('5', $data['data']['best']);
$this->assertEquals('This is the full text of the review', $data['data']['content']['text']);
// $this->assertContains('http://product.example.com/', $data['data']['item']);
// $this->assertArrayHasKey('http://product.example.com/', $data['refs']);
// $this->assertEquals('product', $data['refs']['http://product.example.com/']['type']);
// $this->assertEquals('The Reviewed Product', $data['refs']['http://product.example.com/']['name']);
// $this->assertEquals('http://product.example.com/', $data['refs']['http://product.example.com/']['url']);
// $this->assertArrayHasKey('http://product.example.com/', $data['data']['refs']);
// $this->assertEquals('product', $data['data']['refs']['http://product.example.com/']['type']);
// $this->assertEquals('The Reviewed Product', $data['data']['refs']['http://product.example.com/']['name']);
// $this->assertEquals('http://product.example.com/', $data['data']['refs']['http://product.example.com/']['url']);
}
@ -473,8 +473,8 @@ class ParseTest extends PHPUnit_Framework_TestCase {
$this->assertEquals('entry', $data['data']['type']);
$this->assertEquals('https://www.facebook.com/555707837940351#tantek', $data['data']['url']);
$this->assertContains('https://www.facebook.com/tantek.celik', $data['data']['invitee']);
$this->assertArrayHasKey('https://www.facebook.com/tantek.celik', $data['refs']);
$this->assertEquals('Tantek Çelik', $data['refs']['https://www.facebook.com/tantek.celik']['name']);
$this->assertArrayHasKey('https://www.facebook.com/tantek.celik', $data['data']['refs']);
$this->assertEquals('Tantek Çelik', $data['data']['refs']['https://www.facebook.com/tantek.celik']['name']);
}
public function testEntryAtFragmentID() {
@ -485,6 +485,7 @@ class ParseTest extends PHPUnit_Framework_TestCase {
$this->assertEquals(200, $response->getStatusCode());
$data = json_decode($body, true);
$this->assertEquals('entry', $data['data']['type']);
$this->assertEquals('Comment text', $data['data']['content']['text']);
$this->assertEquals('http://source.example.com/fragment-id#comment-1000', $data['data']['url']);
$this->assertTrue($data['info']['found_fragment']);
}

Loading…
Cancel
Save