diff options
author | adev <adev2000@gmail.com> | 2017-10-24 22:55:40 +0200 |
---|---|---|
committer | Jeremy Benoist <jeremy.benoist@gmail.com> | 2019-05-28 11:40:41 +0200 |
commit | bf9ace0643f654e7ccd9c020b8b501ad56cd19de (patch) | |
tree | 4ff47ca915eb326307127b1b4caf69beda4036e3 | |
parent | 92a66835624acf6fd14f5adc5f8aab399658592e (diff) | |
download | wallabag-bf9ace0643f654e7ccd9c020b8b501ad56cd19de.tar.gz wallabag-bf9ace0643f654e7ccd9c020b8b501ad56cd19de.tar.zst wallabag-bf9ace0643f654e7ccd9c020b8b501ad56cd19de.zip |
Use httplug
-rw-r--r-- | app/AppKernel.php | 1 | ||||
-rw-r--r-- | app/config/config.yml | 19 | ||||
-rw-r--r-- | composer.json | 12 | ||||
-rw-r--r-- | src/Wallabag/CoreBundle/Helper/DownloadImages.php | 21 | ||||
-rw-r--r-- | src/Wallabag/CoreBundle/Helper/HttpClientFactory.php | 47 | ||||
-rw-r--r-- | src/Wallabag/CoreBundle/Resources/config/services.yml | 11 | ||||
-rw-r--r-- | src/Wallabag/ImportBundle/Import/PocketImport.php | 90 | ||||
-rw-r--r-- | src/Wallabag/ImportBundle/Resources/config/services.yml | 8 | ||||
-rw-r--r-- | tests/Wallabag/CoreBundle/Helper/DownloadImagesTest.php | 79 | ||||
-rw-r--r-- | tests/Wallabag/ImportBundle/Import/PocketImportTest.php | 404 |
10 files changed, 324 insertions, 368 deletions
diff --git a/app/AppKernel.php b/app/AppKernel.php index 7d19e9ab..4a54da29 100644 --- a/app/AppKernel.php +++ b/app/AppKernel.php | |||
@@ -34,6 +34,7 @@ class AppKernel extends Kernel | |||
34 | new FOS\JsRoutingBundle\FOSJsRoutingBundle(), | 34 | new FOS\JsRoutingBundle\FOSJsRoutingBundle(), |
35 | new BD\GuzzleSiteAuthenticatorBundle\BDGuzzleSiteAuthenticatorBundle(), | 35 | new BD\GuzzleSiteAuthenticatorBundle\BDGuzzleSiteAuthenticatorBundle(), |
36 | new OldSound\RabbitMqBundle\OldSoundRabbitMqBundle(), | 36 | new OldSound\RabbitMqBundle\OldSoundRabbitMqBundle(), |
37 | new Http\HttplugBundle\HttplugBundle(), | ||
37 | 38 | ||
38 | // wallabag bundles | 39 | // wallabag bundles |
39 | new Wallabag\CoreBundle\WallabagCoreBundle(), | 40 | new Wallabag\CoreBundle\WallabagCoreBundle(), |
diff --git a/app/config/config.yml b/app/config/config.yml index 078f277a..309945c5 100644 --- a/app/config/config.yml +++ b/app/config/config.yml | |||
@@ -370,3 +370,22 @@ jms_serializer: | |||
370 | sensio_framework_extra: | 370 | sensio_framework_extra: |
371 | router: | 371 | router: |
372 | annotations: false | 372 | annotations: false |
373 | |||
374 | httplug: | ||
375 | clients: | ||
376 | wallabag_core: | ||
377 | factory: 'wallabag_core.http_client_factory' | ||
378 | plugins: ['httplug.plugin.logger'] | ||
379 | wallabag_core.entry.download_images: | ||
380 | factory: 'httplug.factory.auto' | ||
381 | plugins: ['httplug.plugin.logger'] | ||
382 | wallabag_import.pocket.client: | ||
383 | factory: 'httplug.factory.auto' | ||
384 | plugins: | ||
385 | - 'httplug.plugin.logger' | ||
386 | - header_defaults: | ||
387 | headers: | ||
388 | 'content-type': 'application/json' | ||
389 | 'X-Accept': 'application/json' | ||
390 | discovery: | ||
391 | client: false | ||
diff --git a/composer.json b/composer.json index b1c144c7..55e7f765 100644 --- a/composer.json +++ b/composer.json | |||
@@ -66,8 +66,9 @@ | |||
66 | "simplepie/simplepie": "~1.5", | 66 | "simplepie/simplepie": "~1.5", |
67 | "willdurand/hateoas-bundle": "~1.3", | 67 | "willdurand/hateoas-bundle": "~1.3", |
68 | "liip/theme-bundle": "^1.4.6", | 68 | "liip/theme-bundle": "^1.4.6", |
69 | "lexik/form-filter-bundle": "^5.0", | 69 | "lexik/form-filter-bundle": "^5.0.4", |
70 | "j0k3r/graby": "^1.0", | 70 | "j0k3r/graby": "^2.0", |
71 | "php-http/guzzle5-adapter": "^2.0", | ||
71 | "friendsofsymfony/user-bundle": "2.0.*", | 72 | "friendsofsymfony/user-bundle": "2.0.*", |
72 | "friendsofsymfony/oauth-server-bundle": "^1.5", | 73 | "friendsofsymfony/oauth-server-bundle": "^1.5", |
73 | "stof/doctrine-extensions-bundle": "^1.2", | 74 | "stof/doctrine-extensions-bundle": "^1.2", |
@@ -89,7 +90,8 @@ | |||
89 | "bdunogier/guzzle-site-authenticator": "^1.0.0", | 90 | "bdunogier/guzzle-site-authenticator": "^1.0.0", |
90 | "defuse/php-encryption": "^2.1", | 91 | "defuse/php-encryption": "^2.1", |
91 | "html2text/html2text": "^4.1", | 92 | "html2text/html2text": "^4.1", |
92 | "pragmarx/recovery": "^0.1.0" | 93 | "pragmarx/recovery": "^0.1.0", |
94 | "php-http/httplug-bundle": "^1.14" | ||
93 | }, | 95 | }, |
94 | "require-dev": { | 96 | "require-dev": { |
95 | "doctrine/doctrine-fixtures-bundle": "~3.0", | 97 | "doctrine/doctrine-fixtures-bundle": "~3.0", |
@@ -101,7 +103,9 @@ | |||
101 | "phpstan/phpstan": "^0.11.0", | 103 | "phpstan/phpstan": "^0.11.0", |
102 | "phpstan/phpstan-phpunit": "^0.11.0", | 104 | "phpstan/phpstan-phpunit": "^0.11.0", |
103 | "phpstan/phpstan-symfony": "^0.11.0", | 105 | "phpstan/phpstan-symfony": "^0.11.0", |
104 | "phpstan/phpstan-doctrine": "^0.11.0" | 106 | "phpstan/phpstan-doctrine": "^0.11.0", |
107 | "php-http/mock-client": "^1.0", | ||
108 | "guzzlehttp/psr7": "^1.0" | ||
105 | }, | 109 | }, |
106 | "suggest": { | 110 | "suggest": { |
107 | "ext-imagick": "To keep GIF animation when downloading image is enabled" | 111 | "ext-imagick": "To keep GIF animation when downloading image is enabled" |
diff --git a/src/Wallabag/CoreBundle/Helper/DownloadImages.php b/src/Wallabag/CoreBundle/Helper/DownloadImages.php index c1645e45..e5749060 100644 --- a/src/Wallabag/CoreBundle/Helper/DownloadImages.php +++ b/src/Wallabag/CoreBundle/Helper/DownloadImages.php | |||
@@ -2,8 +2,13 @@ | |||
2 | 2 | ||
3 | namespace Wallabag\CoreBundle\Helper; | 3 | namespace Wallabag\CoreBundle\Helper; |
4 | 4 | ||
5 | use GuzzleHttp\Client; | 5 | use Http\Client\Common\HttpMethodsClient; |
6 | use GuzzleHttp\Message\Response; | 6 | use Http\Client\Common\Plugin\ErrorPlugin; |
7 | use Http\Client\Common\PluginClient; | ||
8 | use Http\Client\HttpClient; | ||
9 | use Http\Discovery\MessageFactoryDiscovery; | ||
10 | use Http\Message\MessageFactory; | ||
11 | use Psr\Http\Message\ResponseInterface; | ||
7 | use Psr\Log\LoggerInterface; | 12 | use Psr\Log\LoggerInterface; |
8 | use Symfony\Component\DomCrawler\Crawler; | 13 | use Symfony\Component\DomCrawler\Crawler; |
9 | use Symfony\Component\Finder\Finder; | 14 | use Symfony\Component\Finder\Finder; |
@@ -19,9 +24,9 @@ class DownloadImages | |||
19 | private $mimeGuesser; | 24 | private $mimeGuesser; |
20 | private $wallabagUrl; | 25 | private $wallabagUrl; |
21 | 26 | ||
22 | public function __construct(Client $client, $baseFolder, $wallabagUrl, LoggerInterface $logger) | 27 | public function __construct(HttpClient $client, $baseFolder, $wallabagUrl, LoggerInterface $logger, MessageFactory $messageFactory = null) |
23 | { | 28 | { |
24 | $this->client = $client; | 29 | $this->client = new HttpMethodsClient(new PluginClient($client, [new ErrorPlugin()]), $messageFactory ?: MessageFactoryDiscovery::find()); |
25 | $this->baseFolder = $baseFolder; | 30 | $this->baseFolder = $baseFolder; |
26 | $this->wallabagUrl = rtrim($wallabagUrl, '/'); | 31 | $this->wallabagUrl = rtrim($wallabagUrl, '/'); |
27 | $this->logger = $logger; | 32 | $this->logger = $logger; |
@@ -135,7 +140,7 @@ class DownloadImages | |||
135 | $localPath = $folderPath . '/' . $hashImage . '.' . $ext; | 140 | $localPath = $folderPath . '/' . $hashImage . '.' . $ext; |
136 | 141 | ||
137 | try { | 142 | try { |
138 | $im = imagecreatefromstring($res->getBody()); | 143 | $im = imagecreatefromstring((string) $res->getBody()); |
139 | } catch (\Exception $e) { | 144 | } catch (\Exception $e) { |
140 | $im = false; | 145 | $im = false; |
141 | } | 146 | } |
@@ -306,14 +311,14 @@ class DownloadImages | |||
306 | /** | 311 | /** |
307 | * Retrieve and validate the extension from the response of the url of the image. | 312 | * Retrieve and validate the extension from the response of the url of the image. |
308 | * | 313 | * |
309 | * @param Response $res Guzzle Response | 314 | * @param ResponseInterface $res Http Response |
310 | * @param string $imagePath Path from the src image from the content (used for log only) | 315 | * @param string $imagePath Path from the src image from the content (used for log only) |
311 | * | 316 | * |
312 | * @return string|false Extension name or false if validation failed | 317 | * @return string|false Extension name or false if validation failed |
313 | */ | 318 | */ |
314 | private function getExtensionFromResponse(Response $res, $imagePath) | 319 | private function getExtensionFromResponse(ResponseInterface $res, $imagePath) |
315 | { | 320 | { |
316 | $ext = $this->mimeGuesser->guess($res->getHeader('content-type')); | 321 | $ext = $this->mimeGuesser->guess(current($res->getHeader('content-type'))); |
317 | $this->logger->debug('DownloadImages: Checking extension', ['ext' => $ext, 'header' => $res->getHeader('content-type')]); | 322 | $this->logger->debug('DownloadImages: Checking extension', ['ext' => $ext, 'header' => $res->getHeader('content-type')]); |
318 | 323 | ||
319 | // ok header doesn't have the extension, try a different way | 324 | // ok header doesn't have the extension, try a different way |
diff --git a/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php b/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php index 4602a684..4899d3d4 100644 --- a/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php +++ b/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php | |||
@@ -2,16 +2,18 @@ | |||
2 | 2 | ||
3 | namespace Wallabag\CoreBundle\Helper; | 3 | namespace Wallabag\CoreBundle\Helper; |
4 | 4 | ||
5 | use Graby\Ring\Client\SafeCurlHandler; | 5 | use GuzzleHttp\Client as GuzzleClient; |
6 | use GuzzleHttp\Client; | ||
7 | use GuzzleHttp\Cookie\CookieJar; | 6 | use GuzzleHttp\Cookie\CookieJar; |
8 | use GuzzleHttp\Event\SubscriberInterface; | 7 | use GuzzleHttp\Event\SubscriberInterface; |
8 | use Http\Adapter\Guzzle5\Client as GuzzleAdapter; | ||
9 | use Psr\Log\LoggerInterface; | 9 | use Psr\Log\LoggerInterface; |
10 | use Http\Client\HttpClient; | ||
11 | use Http\HttplugBundle\ClientFactory\ClientFactory; | ||
10 | 12 | ||
11 | /** | 13 | /** |
12 | * Builds and configures the Guzzle HTTP client. | 14 | * Builds and configures the HTTP client. |
13 | */ | 15 | */ |
14 | class HttpClientFactory | 16 | class HttpClientFactory implements ClientFactory |
15 | { | 17 | { |
16 | /** @var [\GuzzleHttp\Event\SubscriberInterface] */ | 18 | /** @var [\GuzzleHttp\Event\SubscriberInterface] */ |
17 | private $subscribers = []; | 19 | private $subscribers = []; |
@@ -37,35 +39,38 @@ class HttpClientFactory | |||
37 | } | 39 | } |
38 | 40 | ||
39 | /** | 41 | /** |
40 | * @return \GuzzleHttp\Client|null | 42 | * Adds a subscriber to the HTTP client. |
43 | * | ||
44 | * @param SubscriberInterface $subscriber | ||
45 | */ | ||
46 | public function addSubscriber(SubscriberInterface $subscriber) | ||
47 | { | ||
48 | $this->subscribers[] = $subscriber; | ||
49 | } | ||
50 | |||
51 | /** | ||
52 | * Input an array of configuration to be able to create a HttpClient. | ||
53 | * | ||
54 | * @param array $config | ||
55 | * | ||
56 | * @return HttpClient | ||
41 | */ | 57 | */ |
42 | public function buildHttpClient() | 58 | public function createClient(array $config = []) |
43 | { | 59 | { |
44 | $this->logger->log('debug', 'Restricted access config enabled?', ['enabled' => (int) $this->restrictedAccess]); | 60 | $this->logger->log('debug', 'Restricted access config enabled?', ['enabled' => (int) $this->restrictedAccess]); |
45 | 61 | ||
46 | if (0 === (int) $this->restrictedAccess) { | 62 | if (0 === (int) $this->restrictedAccess) { |
47 | return; | 63 | return new GuzzleAdapter(new GuzzleClient()); |
48 | } | 64 | } |
49 | 65 | ||
50 | // we clear the cookie to avoid websites who use cookies for analytics | 66 | // we clear the cookie to avoid websites who use cookies for analytics |
51 | $this->cookieJar->clear(); | 67 | $this->cookieJar->clear(); |
52 | // need to set the (shared) cookie jar | 68 | // need to set the (shared) cookie jar |
53 | $client = new Client(['handler' => new SafeCurlHandler(), 'defaults' => ['cookies' => $this->cookieJar]]); | 69 | $guzzle = new GuzzleClient(['defaults' => ['cookies' => $this->cookieJar]]); |
54 | |||
55 | foreach ($this->subscribers as $subscriber) { | 70 | foreach ($this->subscribers as $subscriber) { |
56 | $client->getEmitter()->attach($subscriber); | 71 | $guzzle->getEmitter()->attach($subscriber); |
57 | } | 72 | } |
58 | 73 | ||
59 | return $client; | 74 | return new GuzzleAdapter($guzzle); |
60 | } | ||
61 | |||
62 | /** | ||
63 | * Adds a subscriber to the HTTP client. | ||
64 | * | ||
65 | * @param SubscriberInterface $subscriber | ||
66 | */ | ||
67 | public function addSubscriber(SubscriberInterface $subscriber) | ||
68 | { | ||
69 | $this->subscribers[] = $subscriber; | ||
70 | } | 75 | } |
71 | } | 76 | } |
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml index 280d779d..31986951 100644 --- a/src/Wallabag/CoreBundle/Resources/config/services.yml +++ b/src/Wallabag/CoreBundle/Resources/config/services.yml | |||
@@ -42,7 +42,7 @@ services: | |||
42 | - | 42 | - |
43 | error_message: '%wallabag_core.fetching_error_message%' | 43 | error_message: '%wallabag_core.fetching_error_message%' |
44 | error_message_title: '%wallabag_core.fetching_error_message_title%' | 44 | error_message_title: '%wallabag_core.fetching_error_message_title%' |
45 | - "@wallabag_core.guzzle.http_client" | 45 | - "@wallabag_core.http_client" |
46 | - "@wallabag_core.graby.config_builder" | 46 | - "@wallabag_core.graby.config_builder" |
47 | calls: | 47 | calls: |
48 | - [ setLogger, [ "@logger" ] ] | 48 | - [ setLogger, [ "@logger" ] ] |
@@ -55,9 +55,8 @@ services: | |||
55 | - {} | 55 | - {} |
56 | - "@logger" | 56 | - "@logger" |
57 | 57 | ||
58 | wallabag_core.guzzle.http_client: | 58 | wallabag_core.http_client: |
59 | class: GuzzleHttp\ClientInterface | 59 | alias: 'httplug.client.wallabag_core' |
60 | factory: ["@wallabag_core.guzzle.http_client_factory", buildHttpClient] | ||
61 | 60 | ||
62 | wallabag_core.guzzle_authenticator.config_builder: | 61 | wallabag_core.guzzle_authenticator.config_builder: |
63 | class: Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder | 62 | class: Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder |
@@ -73,7 +72,7 @@ services: | |||
73 | bd_guzzle_site_authenticator.site_config_builder: | 72 | bd_guzzle_site_authenticator.site_config_builder: |
74 | alias: wallabag_core.guzzle_authenticator.config_builder | 73 | alias: wallabag_core.guzzle_authenticator.config_builder |
75 | 74 | ||
76 | wallabag_core.guzzle.http_client_factory: | 75 | wallabag_core.http_client_factory: |
77 | class: Wallabag\CoreBundle\Helper\HttpClientFactory | 76 | class: Wallabag\CoreBundle\Helper\HttpClientFactory |
78 | arguments: | 77 | arguments: |
79 | - "@wallabag_core.guzzle.cookie_jar" | 78 | - "@wallabag_core.guzzle.cookie_jar" |
@@ -212,7 +211,7 @@ services: | |||
212 | - "@logger" | 211 | - "@logger" |
213 | 212 | ||
214 | wallabag_core.entry.download_images.client: | 213 | wallabag_core.entry.download_images.client: |
215 | class: GuzzleHttp\Client | 214 | alias: 'httplug.client.wallabag_core.entry.download_images' |
216 | 215 | ||
217 | wallabag_core.helper.crypto_proxy: | 216 | wallabag_core.helper.crypto_proxy: |
218 | class: Wallabag\CoreBundle\Helper\CryptoProxy | 217 | class: Wallabag\CoreBundle\Helper\CryptoProxy |
diff --git a/src/Wallabag/ImportBundle/Import/PocketImport.php b/src/Wallabag/ImportBundle/Import/PocketImport.php index a39d8156..9467fae2 100644 --- a/src/Wallabag/ImportBundle/Import/PocketImport.php +++ b/src/Wallabag/ImportBundle/Import/PocketImport.php | |||
@@ -2,13 +2,22 @@ | |||
2 | 2 | ||
3 | namespace Wallabag\ImportBundle\Import; | 3 | namespace Wallabag\ImportBundle\Import; |
4 | 4 | ||
5 | use GuzzleHttp\Client; | 5 | use Http\Client\Common\HttpMethodsClient; |
6 | use GuzzleHttp\Exception\RequestException; | 6 | use Http\Client\Common\Plugin\ErrorPlugin; |
7 | use Http\Client\Common\PluginClient; | ||
8 | use Http\Client\HttpClient; | ||
9 | use Http\Discovery\MessageFactoryDiscovery; | ||
10 | use Http\Message\MessageFactory; | ||
11 | use Http\Client\Exception\RequestException; | ||
7 | use Wallabag\CoreBundle\Entity\Entry; | 12 | use Wallabag\CoreBundle\Entity\Entry; |
13 | use Psr\Http\Message\ResponseInterface; | ||
8 | 14 | ||
9 | class PocketImport extends AbstractImport | 15 | class PocketImport extends AbstractImport |
10 | { | 16 | { |
11 | const NB_ELEMENTS = 5000; | 17 | const NB_ELEMENTS = 5000; |
18 | /** | ||
19 | * @var HttpMethodsClient | ||
20 | */ | ||
12 | private $client; | 21 | private $client; |
13 | private $accessToken; | 22 | private $accessToken; |
14 | 23 | ||
@@ -55,24 +64,18 @@ class PocketImport extends AbstractImport | |||
55 | */ | 64 | */ |
56 | public function getRequestToken($redirectUri) | 65 | public function getRequestToken($redirectUri) |
57 | { | 66 | { |
58 | $request = $this->client->createRequest('POST', 'https://getpocket.com/v3/oauth/request', | ||
59 | [ | ||
60 | 'body' => json_encode([ | ||
61 | 'consumer_key' => $this->user->getConfig()->getPocketConsumerKey(), | ||
62 | 'redirect_uri' => $redirectUri, | ||
63 | ]), | ||
64 | ] | ||
65 | ); | ||
66 | |||
67 | try { | 67 | try { |
68 | $response = $this->client->send($request); | 68 | $response = $this->client->post('https://getpocket.com/v3/oauth/request', [], json_encode([ |
69 | 'consumer_key' => $this->user->getConfig()->getPocketConsumerKey(), | ||
70 | 'redirect_uri' => $redirectUri, | ||
71 | ])); | ||
69 | } catch (RequestException $e) { | 72 | } catch (RequestException $e) { |
70 | $this->logger->error(sprintf('PocketImport: Failed to request token: %s', $e->getMessage()), ['exception' => $e]); | 73 | $this->logger->error(sprintf('PocketImport: Failed to request token: %s', $e->getMessage()), ['exception' => $e]); |
71 | 74 | ||
72 | return false; | 75 | return false; |
73 | } | 76 | } |
74 | 77 | ||
75 | return $response->json()['code']; | 78 | return $this->jsonDecode($response)['code']; |
76 | } | 79 | } |
77 | 80 | ||
78 | /** | 81 | /** |
@@ -85,24 +88,19 @@ class PocketImport extends AbstractImport | |||
85 | */ | 88 | */ |
86 | public function authorize($code) | 89 | public function authorize($code) |
87 | { | 90 | { |
88 | $request = $this->client->createRequest('POST', 'https://getpocket.com/v3/oauth/authorize', | ||
89 | [ | ||
90 | 'body' => json_encode([ | ||
91 | 'consumer_key' => $this->user->getConfig()->getPocketConsumerKey(), | ||
92 | 'code' => $code, | ||
93 | ]), | ||
94 | ] | ||
95 | ); | ||
96 | 91 | ||
97 | try { | 92 | try { |
98 | $response = $this->client->send($request); | 93 | $response = $this->client->post('https://getpocket.com/v3/oauth/authorize', [], json_encode([ |
94 | 'consumer_key' => $this->user->getConfig()->getPocketConsumerKey(), | ||
95 | 'code' => $code, | ||
96 | ])); | ||
99 | } catch (RequestException $e) { | 97 | } catch (RequestException $e) { |
100 | $this->logger->error(sprintf('PocketImport: Failed to authorize client: %s', $e->getMessage()), ['exception' => $e]); | 98 | $this->logger->error(sprintf('PocketImport: Failed to authorize client: %s', $e->getMessage()), ['exception' => $e]); |
101 | 99 | ||
102 | return false; | 100 | return false; |
103 | } | 101 | } |
104 | 102 | ||
105 | $this->accessToken = $response->json()['access_token']; | 103 | $this->accessToken = $this->jsonDecode($response)['access_token']; |
106 | 104 | ||
107 | return true; | 105 | return true; |
108 | } | 106 | } |
@@ -114,29 +112,23 @@ class PocketImport extends AbstractImport | |||
114 | { | 112 | { |
115 | static $run = 0; | 113 | static $run = 0; |
116 | 114 | ||
117 | $request = $this->client->createRequest('POST', 'https://getpocket.com/v3/get', | ||
118 | [ | ||
119 | 'body' => json_encode([ | ||
120 | 'consumer_key' => $this->user->getConfig()->getPocketConsumerKey(), | ||
121 | 'access_token' => $this->accessToken, | ||
122 | 'detailType' => 'complete', | ||
123 | 'state' => 'all', | ||
124 | 'sort' => 'newest', | ||
125 | 'count' => self::NB_ELEMENTS, | ||
126 | 'offset' => $offset, | ||
127 | ]), | ||
128 | ] | ||
129 | ); | ||
130 | |||
131 | try { | 115 | try { |
132 | $response = $this->client->send($request); | 116 | $response = $this->client->post('https://getpocket.com/v3/get', [], json_encode([ |
117 | 'consumer_key' => $this->user->getConfig()->getPocketConsumerKey(), | ||
118 | 'access_token' => $this->accessToken, | ||
119 | 'detailType' => 'complete', | ||
120 | 'state' => 'all', | ||
121 | 'sort' => 'newest', | ||
122 | 'count' => self::NB_ELEMENTS, | ||
123 | 'offset' => $offset, | ||
124 | ])); | ||
133 | } catch (RequestException $e) { | 125 | } catch (RequestException $e) { |
134 | $this->logger->error(sprintf('PocketImport: Failed to import: %s', $e->getMessage()), ['exception' => $e]); | 126 | $this->logger->error(sprintf('PocketImport: Failed to import: %s', $e->getMessage()), ['exception' => $e]); |
135 | 127 | ||
136 | return false; | 128 | return false; |
137 | } | 129 | } |
138 | 130 | ||
139 | $entries = $response->json(); | 131 | $entries = $this->jsonDecode($response); |
140 | 132 | ||
141 | if ($this->producer) { | 133 | if ($this->producer) { |
142 | $this->parseEntriesForProducer($entries['list']); | 134 | $this->parseEntriesForProducer($entries['list']); |
@@ -159,13 +151,14 @@ class PocketImport extends AbstractImport | |||
159 | } | 151 | } |
160 | 152 | ||
161 | /** | 153 | /** |
162 | * Set the Guzzle client. | 154 | * Set the Http client. |
163 | * | 155 | * |
164 | * @param Client $client | 156 | * @param HttpClient $client |
157 | * @param MessageFactory|null $messageFactory | ||
165 | */ | 158 | */ |
166 | public function setClient(Client $client) | 159 | public function setClient(HttpClient $client, MessageFactory $messageFactory = null) |
167 | { | 160 | { |
168 | $this->client = $client; | 161 | $this->client = new HttpMethodsClient(new PluginClient($client, [new ErrorPlugin()]), $messageFactory ?: MessageFactoryDiscovery::find()); |
169 | } | 162 | } |
170 | 163 | ||
171 | /** | 164 | /** |
@@ -252,4 +245,15 @@ class PocketImport extends AbstractImport | |||
252 | 245 | ||
253 | return $importedEntry; | 246 | return $importedEntry; |
254 | } | 247 | } |
248 | |||
249 | protected function jsonDecode(ResponseInterface $response) | ||
250 | { | ||
251 | $data = \json_decode((string) $response->getBody(), true); | ||
252 | |||
253 | if (JSON_ERROR_NONE !== json_last_error()) { | ||
254 | throw new \InvalidArgumentException('Unable to parse JSON data: ' . json_last_error_msg()); | ||
255 | } | ||
256 | |||
257 | return $data; | ||
258 | } | ||
255 | } | 259 | } |
diff --git a/src/Wallabag/ImportBundle/Resources/config/services.yml b/src/Wallabag/ImportBundle/Resources/config/services.yml index 2dd7dff8..973c0d03 100644 --- a/src/Wallabag/ImportBundle/Resources/config/services.yml +++ b/src/Wallabag/ImportBundle/Resources/config/services.yml | |||
@@ -7,13 +7,7 @@ services: | |||
7 | class: Wallabag\ImportBundle\Import\ImportChain | 7 | class: Wallabag\ImportBundle\Import\ImportChain |
8 | 8 | ||
9 | wallabag_import.pocket.client: | 9 | wallabag_import.pocket.client: |
10 | class: GuzzleHttp\Client | 10 | alias: 'httplug.client.wallabag_import.pocket.client' |
11 | arguments: | ||
12 | - | ||
13 | defaults: | ||
14 | headers: | ||
15 | content-type: "application/json" | ||
16 | X-Accept: "application/json" | ||
17 | 11 | ||
18 | wallabag_import.pocket.import: | 12 | wallabag_import.pocket.import: |
19 | class: Wallabag\ImportBundle\Import\PocketImport | 13 | class: Wallabag\ImportBundle\Import\PocketImport |
diff --git a/tests/Wallabag/CoreBundle/Helper/DownloadImagesTest.php b/tests/Wallabag/CoreBundle/Helper/DownloadImagesTest.php index cda5f843..53758364 100644 --- a/tests/Wallabag/CoreBundle/Helper/DownloadImagesTest.php +++ b/tests/Wallabag/CoreBundle/Helper/DownloadImagesTest.php | |||
@@ -3,9 +3,10 @@ | |||
3 | namespace Tests\Wallabag\CoreBundle\Helper; | 3 | namespace Tests\Wallabag\CoreBundle\Helper; |
4 | 4 | ||
5 | use GuzzleHttp\Client; | 5 | use GuzzleHttp\Client; |
6 | use GuzzleHttp\Message\Response; | ||
7 | use GuzzleHttp\Stream\Stream; | 6 | use GuzzleHttp\Stream\Stream; |
8 | use GuzzleHttp\Subscriber\Mock; | 7 | use GuzzleHttp\Subscriber\Mock; |
8 | use Http\Mock\Client as HttpMockClient; | ||
9 | use GuzzleHttp\Psr7\Response; | ||
9 | use Monolog\Handler\TestHandler; | 10 | use Monolog\Handler\TestHandler; |
10 | use Monolog\Logger; | 11 | use Monolog\Logger; |
11 | use PHPUnit\Framework\TestCase; | 12 | use PHPUnit\Framework\TestCase; |
@@ -32,18 +33,14 @@ class DownloadImagesTest extends TestCase | |||
32 | */ | 33 | */ |
33 | public function testProcessHtml($html, $url) | 34 | public function testProcessHtml($html, $url) |
34 | { | 35 | { |
35 | $client = new Client(); | 36 | $httpMockClient = new HttpMockClient(); |
36 | 37 | ||
37 | $mock = new Mock([ | 38 | $httpMockClient->addResponse(new Response(200, ['content-type' => 'image/png'], file_get_contents(__DIR__ . '/../fixtures/unnamed.png'))); |
38 | new Response(200, ['content-type' => 'image/png'], Stream::factory(file_get_contents(__DIR__ . '/../fixtures/unnamed.png'))), | ||
39 | ]); | ||
40 | |||
41 | $client->getEmitter()->attach($mock); | ||
42 | 39 | ||
43 | $logHandler = new TestHandler(); | 40 | $logHandler = new TestHandler(); |
44 | $logger = new Logger('test', [$logHandler]); | 41 | $logger = new Logger('test', [$logHandler]); |
45 | 42 | ||
46 | $download = new DownloadImages($client, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger); | 43 | $download = new DownloadImages($httpMockClient, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger); |
47 | 44 | ||
48 | $res = $download->processHtml(123, $html, $url); | 45 | $res = $download->processHtml(123, $html, $url); |
49 | 46 | ||
@@ -53,18 +50,13 @@ class DownloadImagesTest extends TestCase | |||
53 | 50 | ||
54 | public function testProcessHtmlWithBadImage() | 51 | public function testProcessHtmlWithBadImage() |
55 | { | 52 | { |
56 | $client = new Client(); | 53 | $httpMockClient = new HttpMockClient(); |
57 | 54 | $httpMockClient->addResponse(new Response(200, ['content-type' => 'application/json'], '')); | |
58 | $mock = new Mock([ | ||
59 | new Response(200, ['content-type' => 'application/json'], Stream::factory('')), | ||
60 | ]); | ||
61 | |||
62 | $client->getEmitter()->attach($mock); | ||
63 | 55 | ||
64 | $logHandler = new TestHandler(); | 56 | $logHandler = new TestHandler(); |
65 | $logger = new Logger('test', [$logHandler]); | 57 | $logger = new Logger('test', [$logHandler]); |
66 | 58 | ||
67 | $download = new DownloadImages($client, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger); | 59 | $download = new DownloadImages($httpMockClient, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger); |
68 | $res = $download->processHtml(123, '<div><img src="http://i.imgur.com/T9qgcHc.jpg" /></div>', 'http://imgur.com/gallery/WxtWY'); | 60 | $res = $download->processHtml(123, '<div><img src="http://i.imgur.com/T9qgcHc.jpg" /></div>', 'http://imgur.com/gallery/WxtWY'); |
69 | 61 | ||
70 | $this->assertContains('http://i.imgur.com/T9qgcHc.jpg', $res, 'Image were not replace because of content-type'); | 62 | $this->assertContains('http://i.imgur.com/T9qgcHc.jpg', $res, 'Image were not replace because of content-type'); |
@@ -85,18 +77,13 @@ class DownloadImagesTest extends TestCase | |||
85 | */ | 77 | */ |
86 | public function testProcessSingleImage($header, $extension) | 78 | public function testProcessSingleImage($header, $extension) |
87 | { | 79 | { |
88 | $client = new Client(); | 80 | $httpMockClient = new HttpMockClient(); |
89 | 81 | $httpMockClient->addResponse(new Response(200, ['content-type' => $header], file_get_contents(__DIR__ . '/../fixtures/unnamed.png'))); | |
90 | $mock = new Mock([ | ||
91 | new Response(200, ['content-type' => $header], Stream::factory(file_get_contents(__DIR__ . '/../fixtures/unnamed.png'))), | ||
92 | ]); | ||
93 | |||
94 | $client->getEmitter()->attach($mock); | ||
95 | 82 | ||
96 | $logHandler = new TestHandler(); | 83 | $logHandler = new TestHandler(); |
97 | $logger = new Logger('test', [$logHandler]); | 84 | $logger = new Logger('test', [$logHandler]); |
98 | 85 | ||
99 | $download = new DownloadImages($client, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger); | 86 | $download = new DownloadImages($httpMockClient, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger); |
100 | $res = $download->processSingleImage(123, 'T9qgcHc.jpg', 'http://imgur.com/gallery/WxtWY'); | 87 | $res = $download->processSingleImage(123, 'T9qgcHc.jpg', 'http://imgur.com/gallery/WxtWY'); |
101 | 88 | ||
102 | $this->assertContains('/assets/images/9/b/9b0ead26/ebe60399.' . $extension, $res); | 89 | $this->assertContains('/assets/images/9/b/9b0ead26/ebe60399.' . $extension, $res); |
@@ -104,18 +91,13 @@ class DownloadImagesTest extends TestCase | |||
104 | 91 | ||
105 | public function testProcessSingleImageWithBadUrl() | 92 | public function testProcessSingleImageWithBadUrl() |
106 | { | 93 | { |
107 | $client = new Client(); | 94 | $httpMockClient = new HttpMockClient(); |
108 | 95 | $httpMockClient->addResponse(new Response(404, [])); | |
109 | $mock = new Mock([ | ||
110 | new Response(404, []), | ||
111 | ]); | ||
112 | |||
113 | $client->getEmitter()->attach($mock); | ||
114 | 96 | ||
115 | $logHandler = new TestHandler(); | 97 | $logHandler = new TestHandler(); |
116 | $logger = new Logger('test', [$logHandler]); | 98 | $logger = new Logger('test', [$logHandler]); |
117 | 99 | ||
118 | $download = new DownloadImages($client, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger); | 100 | $download = new DownloadImages($httpMockClient, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger); |
119 | $res = $download->processSingleImage(123, 'T9qgcHc.jpg', 'http://imgur.com/gallery/WxtWY'); | 101 | $res = $download->processSingleImage(123, 'T9qgcHc.jpg', 'http://imgur.com/gallery/WxtWY'); |
120 | 102 | ||
121 | $this->assertFalse($res, 'Image can not be found, so it will not be replaced'); | 103 | $this->assertFalse($res, 'Image can not be found, so it will not be replaced'); |
@@ -123,18 +105,13 @@ class DownloadImagesTest extends TestCase | |||
123 | 105 | ||
124 | public function testProcessSingleImageWithBadImage() | 106 | public function testProcessSingleImageWithBadImage() |
125 | { | 107 | { |
126 | $client = new Client(); | 108 | $httpMockClient = new HttpMockClient(); |
127 | 109 | $httpMockClient->addResponse(new Response(200, ['content-type' => 'image/png'], '')); | |
128 | $mock = new Mock([ | ||
129 | new Response(200, ['content-type' => 'image/png'], Stream::factory('')), | ||
130 | ]); | ||
131 | |||
132 | $client->getEmitter()->attach($mock); | ||
133 | 110 | ||
134 | $logHandler = new TestHandler(); | 111 | $logHandler = new TestHandler(); |
135 | $logger = new Logger('test', [$logHandler]); | 112 | $logger = new Logger('test', [$logHandler]); |
136 | 113 | ||
137 | $download = new DownloadImages($client, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger); | 114 | $download = new DownloadImages($httpMockClient, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger); |
138 | $res = $download->processSingleImage(123, 'http://i.imgur.com/T9qgcHc.jpg', 'http://imgur.com/gallery/WxtWY'); | 115 | $res = $download->processSingleImage(123, 'http://i.imgur.com/T9qgcHc.jpg', 'http://imgur.com/gallery/WxtWY'); |
139 | 116 | ||
140 | $this->assertFalse($res, 'Image can not be loaded, so it will not be replaced'); | 117 | $this->assertFalse($res, 'Image can not be loaded, so it will not be replaced'); |
@@ -142,18 +119,13 @@ class DownloadImagesTest extends TestCase | |||
142 | 119 | ||
143 | public function testProcessSingleImageFailAbsolute() | 120 | public function testProcessSingleImageFailAbsolute() |
144 | { | 121 | { |
145 | $client = new Client(); | 122 | $httpMockClient = new HttpMockClient(); |
146 | 123 | $httpMockClient->addResponse(new Response(200, ['content-type' => 'image/png'], file_get_contents(__DIR__ . '/../fixtures/unnamed.png'))); | |
147 | $mock = new Mock([ | ||
148 | new Response(200, ['content-type' => 'image/png'], Stream::factory(file_get_contents(__DIR__ . '/../fixtures/unnamed.png'))), | ||
149 | ]); | ||
150 | |||
151 | $client->getEmitter()->attach($mock); | ||
152 | 124 | ||
153 | $logHandler = new TestHandler(); | 125 | $logHandler = new TestHandler(); |
154 | $logger = new Logger('test', [$logHandler]); | 126 | $logger = new Logger('test', [$logHandler]); |
155 | 127 | ||
156 | $download = new DownloadImages($client, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger); | 128 | $download = new DownloadImages($httpMockClient, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger); |
157 | $res = $download->processSingleImage(123, '/i.imgur.com/T9qgcHc.jpg', 'imgur.com/gallery/WxtWY'); | 129 | $res = $download->processSingleImage(123, '/i.imgur.com/T9qgcHc.jpg', 'imgur.com/gallery/WxtWY'); |
158 | 130 | ||
159 | $this->assertFalse($res, 'Absolute image can not be determined, so it will not be replaced'); | 131 | $this->assertFalse($res, 'Absolute image can not be determined, so it will not be replaced'); |
@@ -161,18 +133,13 @@ class DownloadImagesTest extends TestCase | |||
161 | 133 | ||
162 | public function testProcessRealImage() | 134 | public function testProcessRealImage() |
163 | { | 135 | { |
164 | $client = new Client(); | 136 | $httpMockClient = new HttpMockClient(); |
165 | 137 | $httpMockClient->addResponse(new Response(200, ['content-type' => null], file_get_contents(__DIR__ . '/../fixtures/image-no-content-type.jpg'))); | |
166 | $mock = new Mock([ | ||
167 | new Response(200, ['content-type' => null], Stream::factory(file_get_contents(__DIR__ . '/../fixtures/image-no-content-type.jpg'))), | ||
168 | ]); | ||
169 | |||
170 | $client->getEmitter()->attach($mock); | ||
171 | 138 | ||
172 | $logHandler = new TestHandler(); | 139 | $logHandler = new TestHandler(); |
173 | $logger = new Logger('test', [$logHandler]); | 140 | $logger = new Logger('test', [$logHandler]); |
174 | 141 | ||
175 | $download = new DownloadImages($client, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger); | 142 | $download = new DownloadImages($httpMockClient, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger); |
176 | 143 | ||
177 | $res = $download->processSingleImage( | 144 | $res = $download->processSingleImage( |
178 | 123, | 145 | 123, |
diff --git a/tests/Wallabag/ImportBundle/Import/PocketImportTest.php b/tests/Wallabag/ImportBundle/Import/PocketImportTest.php index 8083f1a8..ec76f168 100644 --- a/tests/Wallabag/ImportBundle/Import/PocketImportTest.php +++ b/tests/Wallabag/ImportBundle/Import/PocketImportTest.php | |||
@@ -2,10 +2,8 @@ | |||
2 | 2 | ||
3 | namespace Tests\Wallabag\ImportBundle\Import; | 3 | namespace Tests\Wallabag\ImportBundle\Import; |
4 | 4 | ||
5 | use GuzzleHttp\Client; | 5 | use Http\Mock\Client as HttpMockClient; |
6 | use GuzzleHttp\Message\Response; | 6 | use GuzzleHttp\Psr7\Response; |
7 | use GuzzleHttp\Stream\Stream; | ||
8 | use GuzzleHttp\Subscriber\Mock; | ||
9 | use M6Web\Component\RedisMock\RedisMockFactory; | 7 | use M6Web\Component\RedisMock\RedisMockFactory; |
10 | use Monolog\Handler\TestHandler; | 8 | use Monolog\Handler\TestHandler; |
11 | use Monolog\Logger; | 9 | use Monolog\Logger; |
@@ -38,16 +36,11 @@ class PocketImportTest extends TestCase | |||
38 | 36 | ||
39 | public function testOAuthRequest() | 37 | public function testOAuthRequest() |
40 | { | 38 | { |
41 | $client = new Client(); | 39 | $httpMockClient = new HttpMockClient(); |
42 | 40 | $httpMockClient->addResponse(new Response(200, ['Content-Type' => 'application/json'], json_encode(['code' => 'wunderbar_code']))); | |
43 | $mock = new Mock([ | ||
44 | new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['code' => 'wunderbar_code']))), | ||
45 | ]); | ||
46 | |||
47 | $client->getEmitter()->attach($mock); | ||
48 | 41 | ||
49 | $pocketImport = $this->getPocketImport(); | 42 | $pocketImport = $this->getPocketImport(); |
50 | $pocketImport->setClient($client); | 43 | $pocketImport->setClient($httpMockClient); |
51 | 44 | ||
52 | $code = $pocketImport->getRequestToken('http://0.0.0.0/redirect'); | 45 | $code = $pocketImport->getRequestToken('http://0.0.0.0/redirect'); |
53 | 46 | ||
@@ -56,16 +49,11 @@ class PocketImportTest extends TestCase | |||
56 | 49 | ||
57 | public function testOAuthRequestBadResponse() | 50 | public function testOAuthRequestBadResponse() |
58 | { | 51 | { |
59 | $client = new Client(); | 52 | $httpMockClient = new HttpMockClient(); |
60 | 53 | $httpMockClient->addResponse(new Response(403)); | |
61 | $mock = new Mock([ | ||
62 | new Response(403), | ||
63 | ]); | ||
64 | |||
65 | $client->getEmitter()->attach($mock); | ||
66 | 54 | ||
67 | $pocketImport = $this->getPocketImport(); | 55 | $pocketImport = $this->getPocketImport(); |
68 | $pocketImport->setClient($client); | 56 | $pocketImport->setClient($httpMockClient); |
69 | 57 | ||
70 | $code = $pocketImport->getRequestToken('http://0.0.0.0/redirect'); | 58 | $code = $pocketImport->getRequestToken('http://0.0.0.0/redirect'); |
71 | 59 | ||
@@ -78,16 +66,11 @@ class PocketImportTest extends TestCase | |||
78 | 66 | ||
79 | public function testOAuthAuthorize() | 67 | public function testOAuthAuthorize() |
80 | { | 68 | { |
81 | $client = new Client(); | 69 | $httpMockClient = new HttpMockClient(); |
82 | 70 | $httpMockClient->addResponse(new Response(200, ['Content-Type' => 'application/json'], json_encode(['access_token' => 'wunderbar_token']))); | |
83 | $mock = new Mock([ | ||
84 | new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))), | ||
85 | ]); | ||
86 | |||
87 | $client->getEmitter()->attach($mock); | ||
88 | 71 | ||
89 | $pocketImport = $this->getPocketImport(); | 72 | $pocketImport = $this->getPocketImport(); |
90 | $pocketImport->setClient($client); | 73 | $pocketImport->setClient($httpMockClient); |
91 | 74 | ||
92 | $res = $pocketImport->authorize('wunderbar_code'); | 75 | $res = $pocketImport->authorize('wunderbar_code'); |
93 | 76 | ||
@@ -97,16 +80,11 @@ class PocketImportTest extends TestCase | |||
97 | 80 | ||
98 | public function testOAuthAuthorizeBadResponse() | 81 | public function testOAuthAuthorizeBadResponse() |
99 | { | 82 | { |
100 | $client = new Client(); | 83 | $httpMockClient = new HttpMockClient(); |
101 | 84 | $httpMockClient->addResponse(new Response(403)); | |
102 | $mock = new Mock([ | ||
103 | new Response(403), | ||
104 | ]); | ||
105 | |||
106 | $client->getEmitter()->attach($mock); | ||
107 | 85 | ||
108 | $pocketImport = $this->getPocketImport(); | 86 | $pocketImport = $this->getPocketImport(); |
109 | $pocketImport->setClient($client); | 87 | $pocketImport->setClient($httpMockClient); |
110 | 88 | ||
111 | $res = $pocketImport->authorize('wunderbar_code'); | 89 | $res = $pocketImport->authorize('wunderbar_code'); |
112 | 90 | ||
@@ -122,94 +100,90 @@ class PocketImportTest extends TestCase | |||
122 | */ | 100 | */ |
123 | public function testImport() | 101 | public function testImport() |
124 | { | 102 | { |
125 | $client = new Client(); | 103 | $httpMockClient = new HttpMockClient(); |
126 | 104 | $httpMockClient->addResponse(new Response(200, ['Content-Type' => 'application/json'], json_encode(['access_token' => 'wunderbar_token']))); | |
127 | $mock = new Mock([ | 105 | $httpMockClient->addResponse(new Response(200, ['Content-Type' => 'application/json'], <<<'JSON' |
128 | new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))), | 106 | { |
129 | new Response(200, ['Content-Type' => 'application/json'], Stream::factory(' | 107 | "status": 1, |
130 | { | 108 | "list": { |
131 | "status": 1, | 109 | "229279689": { |
132 | "list": { | 110 | "item_id": "229279689", |
133 | "229279689": { | 111 | "resolved_id": "229279689", |
134 | "item_id": "229279689", | 112 | "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview", |
135 | "resolved_id": "229279689", | 113 | "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland", |
136 | "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview", | 114 | "favorite": "1", |
137 | "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland", | 115 | "status": "1", |
138 | "favorite": "1", | 116 | "time_added": "1473020899", |
139 | "status": "1", | 117 | "time_updated": "1473020899", |
140 | "time_added": "1473020899", | 118 | "time_read": "0", |
141 | "time_updated": "1473020899", | 119 | "time_favorited": "0", |
142 | "time_read": "0", | 120 | "sort_id": 0, |
143 | "time_favorited": "0", | 121 | "resolved_title": "The Massive Ryder Cup Preview", |
144 | "sort_id": 0, | 122 | "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview", |
145 | "resolved_title": "The Massive Ryder Cup Preview", | 123 | "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.", |
146 | "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview", | 124 | "is_article": "1", |
147 | "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.", | 125 | "is_index": "0", |
148 | "is_article": "1", | 126 | "has_video": "1", |
149 | "is_index": "0", | 127 | "has_image": "1", |
150 | "has_video": "1", | 128 | "word_count": "3197", |
151 | "has_image": "1", | 129 | "images": { |
152 | "word_count": "3197", | 130 | "1": { |
153 | "images": { | 131 | "item_id": "229279689", |
154 | "1": { | 132 | "image_id": "1", |
155 | "item_id": "229279689", | 133 | "src": "http://a.espncdn.com/combiner/i?img=/photo/2012/0927/grant_g_ryder_cr_640.jpg&w=640&h=360", |
156 | "image_id": "1", | 134 | "width": "0", |
157 | "src": "http://a.espncdn.com/combiner/i?img=/photo/2012/0927/grant_g_ryder_cr_640.jpg&w=640&h=360", | 135 | "height": "0", |
158 | "width": "0", | 136 | "credit": "Jamie Squire/Getty Images", |
159 | "height": "0", | 137 | "caption": "" |
160 | "credit": "Jamie Squire/Getty Images", | ||
161 | "caption": "" | ||
162 | } | ||
163 | }, | ||
164 | "videos": { | ||
165 | "1": { | ||
166 | "item_id": "229279689", | ||
167 | "video_id": "1", | ||
168 | "src": "http://www.youtube.com/v/Er34PbFkVGk?version=3&hl=en_US&rel=0", | ||
169 | "width": "420", | ||
170 | "height": "315", | ||
171 | "type": "1", | ||
172 | "vid": "Er34PbFkVGk" | ||
173 | } | ||
174 | }, | ||
175 | "tags": { | ||
176 | "grantland": { | ||
177 | "item_id": "1147652870", | ||
178 | "tag": "grantland" | ||
179 | }, | ||
180 | "Ryder Cup": { | ||
181 | "item_id": "1147652870", | ||
182 | "tag": "Ryder Cup" | ||
183 | } | ||
184 | } | 138 | } |
185 | }, | 139 | }, |
186 | "229279690": { | 140 | "videos": { |
187 | "item_id": "229279689", | 141 | "1": { |
188 | "resolved_id": "229279689", | 142 | "item_id": "229279689", |
189 | "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview", | 143 | "video_id": "1", |
190 | "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland", | 144 | "src": "http://www.youtube.com/v/Er34PbFkVGk?version=3&hl=en_US&rel=0", |
191 | "favorite": "1", | 145 | "width": "420", |
192 | "status": "1", | 146 | "height": "315", |
193 | "time_added": "1473020899", | 147 | "type": "1", |
194 | "time_updated": "1473020899", | 148 | "vid": "Er34PbFkVGk" |
195 | "time_read": "0", | 149 | } |
196 | "time_favorited": "0", | 150 | }, |
197 | "sort_id": 1, | 151 | "tags": { |
198 | "resolved_title": "The Massive Ryder Cup Preview", | 152 | "grantland": { |
199 | "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview", | 153 | "item_id": "1147652870", |
200 | "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.", | 154 | "tag": "grantland" |
201 | "is_article": "1", | 155 | }, |
202 | "is_index": "0", | 156 | "Ryder Cup": { |
203 | "has_video": "0", | 157 | "item_id": "1147652870", |
204 | "has_image": "0", | 158 | "tag": "Ryder Cup" |
205 | "word_count": "3197" | 159 | } |
206 | } | 160 | } |
161 | }, | ||
162 | "229279690": { | ||
163 | "item_id": "229279689", | ||
164 | "resolved_id": "229279689", | ||
165 | "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview", | ||
166 | "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland", | ||
167 | "favorite": "1", | ||
168 | "status": "1", | ||
169 | "time_added": "1473020899", | ||
170 | "time_updated": "1473020899", | ||
171 | "time_read": "0", | ||
172 | "time_favorited": "0", | ||
173 | "sort_id": 1, | ||
174 | "resolved_title": "The Massive Ryder Cup Preview", | ||
175 | "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview", | ||
176 | "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.", | ||
177 | "is_article": "1", | ||
178 | "is_index": "0", | ||
179 | "has_video": "0", | ||
180 | "has_image": "0", | ||
181 | "word_count": "3197" | ||
207 | } | 182 | } |
208 | } | 183 | } |
209 | ')), | 184 | } |
210 | ]); | 185 | JSON |
211 | 186 | )); | |
212 | $client->getEmitter()->attach($mock); | ||
213 | 187 | ||
214 | $pocketImport = $this->getPocketImport('ConsumerKey', 1); | 188 | $pocketImport = $this->getPocketImport('ConsumerKey', 1); |
215 | 189 | ||
@@ -240,7 +214,7 @@ class PocketImportTest extends TestCase | |||
240 | ->method('updateEntry') | 214 | ->method('updateEntry') |
241 | ->willReturn($entry); | 215 | ->willReturn($entry); |
242 | 216 | ||
243 | $pocketImport->setClient($client); | 217 | $pocketImport->setClient($httpMockClient); |
244 | $pocketImport->authorize('wunderbar_code'); | 218 | $pocketImport->authorize('wunderbar_code'); |
245 | 219 | ||
246 | $res = $pocketImport->import(); | 220 | $res = $pocketImport->import(); |
@@ -254,56 +228,52 @@ class PocketImportTest extends TestCase | |||
254 | */ | 228 | */ |
255 | public function testImportAndMarkAllAsRead() | 229 | public function testImportAndMarkAllAsRead() |
256 | { | 230 | { |
257 | $client = new Client(); | 231 | $httpMockClient = new HttpMockClient(); |
258 | 232 | $httpMockClient->addResponse(new Response(200, ['Content-Type' => 'application/json'], json_encode(['access_token' => 'wunderbar_token']))); | |
259 | $mock = new Mock([ | 233 | $httpMockClient->addResponse(new Response(200, ['Content-Type' => 'application/json'], <<<'JSON' |
260 | new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))), | 234 | { |
261 | new Response(200, ['Content-Type' => 'application/json'], Stream::factory(' | 235 | "status": 1, |
262 | { | 236 | "list": { |
263 | "status": 1, | 237 | "229279689": { |
264 | "list": { | 238 | "item_id": "229279689", |
265 | "229279689": { | 239 | "resolved_id": "229279689", |
266 | "item_id": "229279689", | 240 | "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview", |
267 | "resolved_id": "229279689", | 241 | "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland", |
268 | "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview", | 242 | "favorite": "1", |
269 | "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland", | 243 | "status": "1", |
270 | "favorite": "1", | 244 | "time_added": "1473020899", |
271 | "status": "1", | 245 | "time_updated": "1473020899", |
272 | "time_added": "1473020899", | 246 | "time_read": "0", |
273 | "time_updated": "1473020899", | 247 | "time_favorited": "0", |
274 | "time_read": "0", | 248 | "sort_id": 0, |
275 | "time_favorited": "0", | 249 | "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.", |
276 | "sort_id": 0, | 250 | "is_article": "1", |
277 | "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.", | 251 | "has_video": "1", |
278 | "is_article": "1", | 252 | "has_image": "1", |
279 | "has_video": "1", | 253 | "word_count": "3197" |
280 | "has_image": "1", | 254 | }, |
281 | "word_count": "3197" | 255 | "229279690": { |
282 | }, | 256 | "item_id": "229279689", |
283 | "229279690": { | 257 | "resolved_id": "229279689", |
284 | "item_id": "229279689", | 258 | "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview/2", |
285 | "resolved_id": "229279689", | 259 | "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland", |
286 | "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview/2", | 260 | "favorite": "1", |
287 | "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland", | 261 | "status": "0", |
288 | "favorite": "1", | 262 | "time_added": "1473020899", |
289 | "status": "0", | 263 | "time_updated": "1473020899", |
290 | "time_added": "1473020899", | 264 | "time_read": "0", |
291 | "time_updated": "1473020899", | 265 | "time_favorited": "0", |
292 | "time_read": "0", | 266 | "sort_id": 1, |
293 | "time_favorited": "0", | 267 | "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.", |
294 | "sort_id": 1, | 268 | "is_article": "1", |
295 | "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.", | 269 | "has_video": "0", |
296 | "is_article": "1", | 270 | "has_image": "0", |
297 | "has_video": "0", | 271 | "word_count": "3197" |
298 | "has_image": "0", | ||
299 | "word_count": "3197" | ||
300 | } | ||
301 | } | 272 | } |
302 | } | 273 | } |
303 | ')), | 274 | } |
304 | ]); | 275 | JSON |
305 | 276 | )); | |
306 | $client->getEmitter()->attach($mock); | ||
307 | 277 | ||
308 | $pocketImport = $this->getPocketImport('ConsumerKey', 2); | 278 | $pocketImport = $this->getPocketImport('ConsumerKey', 2); |
309 | 279 | ||
@@ -335,7 +305,7 @@ class PocketImportTest extends TestCase | |||
335 | ->method('updateEntry') | 305 | ->method('updateEntry') |
336 | ->willReturn($entry); | 306 | ->willReturn($entry); |
337 | 307 | ||
338 | $pocketImport->setClient($client); | 308 | $pocketImport->setClient($httpMockClient); |
339 | $pocketImport->authorize('wunderbar_code'); | 309 | $pocketImport->authorize('wunderbar_code'); |
340 | 310 | ||
341 | $res = $pocketImport->setMarkAsRead(true)->import(); | 311 | $res = $pocketImport->setMarkAsRead(true)->import(); |
@@ -349,7 +319,7 @@ class PocketImportTest extends TestCase | |||
349 | */ | 319 | */ |
350 | public function testImportWithRabbit() | 320 | public function testImportWithRabbit() |
351 | { | 321 | { |
352 | $client = new Client(); | 322 | $httpMockClient = new HttpMockClient(); |
353 | 323 | ||
354 | $body = <<<'JSON' | 324 | $body = <<<'JSON' |
355 | { | 325 | { |
@@ -374,19 +344,16 @@ class PocketImportTest extends TestCase | |||
374 | } | 344 | } |
375 | JSON; | 345 | JSON; |
376 | 346 | ||
377 | $mock = new Mock([ | 347 | $httpMockClient->addResponse(new Response(200, ['Content-Type' => 'application/json'], json_encode(['access_token' => 'wunderbar_token']))); |
378 | new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))), | 348 | $httpMockClient->addResponse(new Response(200, ['Content-Type' => 'application/json'], <<<JSON |
379 | new Response(200, ['Content-Type' => 'application/json'], Stream::factory(' | 349 | { |
380 | { | 350 | "status": 1, |
381 | "status": 1, | 351 | "list": { |
382 | "list": { | 352 | "229279690": $body |
383 | "229279690": ' . $body . ' | ||
384 | } | ||
385 | } | 353 | } |
386 | ')), | 354 | } |
387 | ]); | 355 | JSON |
388 | 356 | )); | |
389 | $client->getEmitter()->attach($mock); | ||
390 | 357 | ||
391 | $pocketImport = $this->getPocketImport(); | 358 | $pocketImport = $this->getPocketImport(); |
392 | 359 | ||
@@ -420,7 +387,7 @@ JSON; | |||
420 | ->method('publish') | 387 | ->method('publish') |
421 | ->with(json_encode($bodyAsArray)); | 388 | ->with(json_encode($bodyAsArray)); |
422 | 389 | ||
423 | $pocketImport->setClient($client); | 390 | $pocketImport->setClient($httpMockClient); |
424 | $pocketImport->setProducer($producer); | 391 | $pocketImport->setProducer($producer); |
425 | $pocketImport->authorize('wunderbar_code'); | 392 | $pocketImport->authorize('wunderbar_code'); |
426 | 393 | ||
@@ -435,7 +402,7 @@ JSON; | |||
435 | */ | 402 | */ |
436 | public function testImportWithRedis() | 403 | public function testImportWithRedis() |
437 | { | 404 | { |
438 | $client = new Client(); | 405 | $httpMockClient = new HttpMockClient(); |
439 | 406 | ||
440 | $body = <<<'JSON' | 407 | $body = <<<'JSON' |
441 | { | 408 | { |
@@ -460,19 +427,16 @@ JSON; | |||
460 | } | 427 | } |
461 | JSON; | 428 | JSON; |
462 | 429 | ||
463 | $mock = new Mock([ | 430 | $httpMockClient->addResponse(new Response(200, ['Content-Type' => 'application/json'], json_encode(['access_token' => 'wunderbar_token']))); |
464 | new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))), | 431 | $httpMockClient->addResponse(new Response(200, ['Content-Type' => 'application/json'], <<<JSON |
465 | new Response(200, ['Content-Type' => 'application/json'], Stream::factory(' | 432 | { |
466 | { | 433 | "status": 1, |
467 | "status": 1, | 434 | "list": { |
468 | "list": { | 435 | "229279690": $body |
469 | "229279690": ' . $body . ' | ||
470 | } | ||
471 | } | 436 | } |
472 | ')), | 437 | } |
473 | ]); | 438 | JSON |
474 | 439 | )); | |
475 | $client->getEmitter()->attach($mock); | ||
476 | 440 | ||
477 | $pocketImport = $this->getPocketImport(); | 441 | $pocketImport = $this->getPocketImport(); |
478 | 442 | ||
@@ -499,7 +463,7 @@ JSON; | |||
499 | $queue = new RedisQueue($redisMock, 'pocket'); | 463 | $queue = new RedisQueue($redisMock, 'pocket'); |
500 | $producer = new Producer($queue); | 464 | $producer = new Producer($queue); |
501 | 465 | ||
502 | $pocketImport->setClient($client); | 466 | $pocketImport->setClient($httpMockClient); |
503 | $pocketImport->setProducer($producer); | 467 | $pocketImport->setProducer($producer); |
504 | $pocketImport->authorize('wunderbar_code'); | 468 | $pocketImport->authorize('wunderbar_code'); |
505 | 469 | ||
@@ -513,17 +477,13 @@ JSON; | |||
513 | 477 | ||
514 | public function testImportBadResponse() | 478 | public function testImportBadResponse() |
515 | { | 479 | { |
516 | $client = new Client(); | 480 | $httpMockClient = new HttpMockClient(); |
517 | 481 | ||
518 | $mock = new Mock([ | 482 | $httpMockClient->addResponse(new Response(200, ['Content-Type' => 'application/json'], json_encode(['access_token' => 'wunderbar_token']))); |
519 | new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))), | 483 | $httpMockClient->addResponse(new Response(403)); |
520 | new Response(403), | ||
521 | ]); | ||
522 | |||
523 | $client->getEmitter()->attach($mock); | ||
524 | 484 | ||
525 | $pocketImport = $this->getPocketImport(); | 485 | $pocketImport = $this->getPocketImport(); |
526 | $pocketImport->setClient($client); | 486 | $pocketImport->setClient($httpMockClient); |
527 | $pocketImport->authorize('wunderbar_code'); | 487 | $pocketImport->authorize('wunderbar_code'); |
528 | 488 | ||
529 | $res = $pocketImport->import(); | 489 | $res = $pocketImport->import(); |
@@ -537,25 +497,23 @@ JSON; | |||
537 | 497 | ||
538 | public function testImportWithExceptionFromGraby() | 498 | public function testImportWithExceptionFromGraby() |
539 | { | 499 | { |
540 | $client = new Client(); | 500 | $httpMockClient = new HttpMockClient(); |
541 | 501 | ||
542 | $mock = new Mock([ | 502 | $httpMockClient->addResponse(new Response(200, ['Content-Type' => 'application/json'], json_encode(['access_token' => 'wunderbar_token']))); |
543 | new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))), | 503 | $httpMockClient->addResponse(new Response(200, ['Content-Type' => 'application/json'], <<<'JSON' |
544 | new Response(200, ['Content-Type' => 'application/json'], Stream::factory(' | 504 | { |
545 | { | 505 | "status": 1, |
546 | "status": 1, | 506 | "list": { |
547 | "list": { | 507 | "229279689": { |
548 | "229279689": { | 508 | "status": "1", |
549 | "status": "1", | 509 | "favorite": "1", |
550 | "favorite": "1", | 510 | "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview" |
551 | "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview" | ||
552 | } | ||
553 | } | 511 | } |
554 | } | 512 | } |
555 | ')), | 513 | } |
556 | ]); | 514 | |
557 | 515 | JSON | |
558 | $client->getEmitter()->attach($mock); | 516 | )); |
559 | 517 | ||
560 | $pocketImport = $this->getPocketImport('ConsumerKey', 1); | 518 | $pocketImport = $this->getPocketImport('ConsumerKey', 1); |
561 | 519 | ||
@@ -579,7 +537,7 @@ JSON; | |||
579 | ->method('updateEntry') | 537 | ->method('updateEntry') |
580 | ->will($this->throwException(new \Exception())); | 538 | ->will($this->throwException(new \Exception())); |
581 | 539 | ||
582 | $pocketImport->setClient($client); | 540 | $pocketImport->setClient($httpMockClient); |
583 | $pocketImport->authorize('wunderbar_code'); | 541 | $pocketImport->authorize('wunderbar_code'); |
584 | 542 | ||
585 | $res = $pocketImport->import(); | 543 | $res = $pocketImport->import(); |