aboutsummaryrefslogtreecommitdiff
path: root/vendor/tumblr
diff options
context:
space:
mode:
authorChristian Cleberg <hello@cleberg.net>2023-05-22 15:37:34 -0500
committerChristian Cleberg <hello@cleberg.net>2023-05-22 15:37:34 -0500
commit17ff8aec3a0d2e0a520849c42c40a154a0831495 (patch)
tree8860d29e9d0f9acd1535c7827045864fc31f8d01 /vendor/tumblr
downloadmichelangelo-17ff8aec3a0d2e0a520849c42c40a154a0831495.tar.gz
michelangelo-17ff8aec3a0d2e0a520849c42c40a154a0831495.tar.bz2
michelangelo-17ff8aec3a0d2e0a520849c42c40a154a0831495.zip
initial commit
Diffstat (limited to 'vendor/tumblr')
-rw-r--r--vendor/tumblr/tumblr/.gitignore12
-rw-r--r--vendor/tumblr/tumblr/.travis.yml12
-rw-r--r--vendor/tumblr/tumblr/CONTRIBUTING.md22
-rw-r--r--vendor/tumblr/tumblr/LICENSE202
-rw-r--r--vendor/tumblr/tumblr/README.md109
-rw-r--r--vendor/tumblr/tumblr/composer.json39
-rw-r--r--vendor/tumblr/tumblr/lib/Tumblr/API/Client.php502
-rw-r--r--vendor/tumblr/tumblr/lib/Tumblr/API/RequestException.php35
-rw-r--r--vendor/tumblr/tumblr/lib/Tumblr/API/RequestHandler.php151
-rw-r--r--vendor/tumblr/tumblr/phpunit.xml15
-rw-r--r--vendor/tumblr/tumblr/test/BlogTest.php67
-rw-r--r--vendor/tumblr/tumblr/test/PostTest.php30
-rw-r--r--vendor/tumblr/tumblr/test/RequestExceptionTest.php28
-rw-r--r--vendor/tumblr/tumblr/test/RequestHandlerTest.php71
-rw-r--r--vendor/tumblr/tumblr/test/TaggedTest.php16
-rw-r--r--vendor/tumblr/tumblr/test/TumblrTest.php51
-rw-r--r--vendor/tumblr/tumblr/test/UserTest.php40
-rw-r--r--vendor/tumblr/tumblr/test/bootstrap.php8
18 files changed, 1410 insertions, 0 deletions
diff --git a/vendor/tumblr/tumblr/.gitignore b/vendor/tumblr/tumblr/.gitignore
new file mode 100644
index 0000000..2e61014
--- /dev/null
+++ b/vendor/tumblr/tumblr/.gitignore
@@ -0,0 +1,12 @@
+coverage
+.DS_Store
+
+composer.phar
+
+*.swp
+*.swo
+
+usage.php
+
+vendor
+composer.lock
diff --git a/vendor/tumblr/tumblr/.travis.yml b/vendor/tumblr/tumblr/.travis.yml
new file mode 100644
index 0000000..4986ae4
--- /dev/null
+++ b/vendor/tumblr/tumblr/.travis.yml
@@ -0,0 +1,12 @@
+language: php
+before_script: composer install
+
+php:
+ - 7.1
+ - 7.0
+ - 5.6
+ - hhvm
+
+matrix:
+ allow_failures:
+ - php: hhvm
diff --git a/vendor/tumblr/tumblr/CONTRIBUTING.md b/vendor/tumblr/tumblr/CONTRIBUTING.md
new file mode 100644
index 0000000..e6d97d1
--- /dev/null
+++ b/vendor/tumblr/tumblr/CONTRIBUTING.md
@@ -0,0 +1,22 @@
+# Contributing
+
+We want to make contributing to tumblr.php as easy and transparent as possible. If you run into problems, please open an issue. We also actively welcome pull requests.
+
+## Pull Requests
+
+1. Fork the repo and create your branch from `master`.
+2. If you've added code that should be tested, add tests.
+3. If you've changed APIs, update the documentation.
+4. Ensure the test suite passes.
+5. If you haven't already, complete the Contributor License Agreement ("CLA").
+
+## Contributor License Agreement ("CLA")
+
+In order to accept your pull request, we need you to submit a CLA.
+
+Complete your CLA [here](http://static.tumblr.com/zyubucd/GaTngbrpr/tumblr_corporate_contributor_license_agreement_v1__10-7-14.pdf) (a more integrated web form is coming soon).
+
+## License
+
+By contributing to tumblr.php you agree that your contributions will be licensed under its Apache 2.0 license.
+
diff --git a/vendor/tumblr/tumblr/LICENSE b/vendor/tumblr/tumblr/LICENSE
new file mode 100644
index 0000000..ba74d5c
--- /dev/null
+++ b/vendor/tumblr/tumblr/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2013 Tumblr, Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/tumblr/tumblr/README.md b/vendor/tumblr/tumblr/README.md
new file mode 100644
index 0000000..69a9dd1
--- /dev/null
+++ b/vendor/tumblr/tumblr/README.md
@@ -0,0 +1,109 @@
+# tumblr.php
+
+[![Build Status](https://secure.travis-ci.org/tumblr/tumblr.php.png)](http://travis-ci.org/tumblr/tumblr.php)
+
+The official PHP client for the
+[Tumblr API](http://www.tumblr.com/docs/en/api/v2).
+
+## Usage
+
+### Basic Usage
+
+The first step is setting up a Client:
+
+``` php
+$client = new Tumblr\API\Client($consumerKey, $consumerSecret);
+$client->setToken($token, $tokenSecret);
+```
+
+And then you can do anything you'd like:
+
+``` php
+foreach ($client->getUserInfo()->user->blogs as $blog) {
+ echo $blog->name . "\n";
+}
+```
+
+### User Methods
+
+``` php
+$client->getUserInfo();
+
+$client->getDashboardPosts($options = null);
+$client->getLikedPosts($options = null);
+$client->getFollowedBlogs($options = null);
+
+$client->follow($blogName);
+$client->unfollow($blogName);
+
+$client->like($postId, $reblogKey);
+$client->unlike($postId, $reblogKey);
+```
+
+### Blog Methods
+
+``` php
+$client->getBlogInfo($blogName);
+
+$client->getBlogAvatar($blogName, $size = null);
+
+$client->getBlogPosts($blogName, $options = null);
+$client->getBlogLikes($blogName, $options = null);
+$client->getBlogFollowers($blogName, $options = null);
+
+$client->getQueuedPosts($blogName, $options = null);
+$client->getDraftPosts($blogName, $options = null);
+$client->getSubmissionPosts($blogName, $options = null);
+```
+
+### Post Methods
+
+``` php
+$client->createPost($blogName, $data);
+$client->editPost($blogName, $id, $data);
+$client->deletePost($blogName, $id, $reblogKey);
+$client->reblogPost($blogName, $id, $reblogKey, $options = null);
+```
+
+### Tagged Methods
+
+``` php
+$client->getTaggedPosts($tag, $options = null);
+```
+
+## Dependencies
+
+tumblr.php is available
+[on composer](https://packagist.org/packages/tumblr/tumblr)
+
+* guzzle/guzzle 6.*
+* eher/oauth 1.0.x
+
+If you're using composer (you should!) you can just run
+`php composer.phar install` and you'll be good to go. More details on
+[getcomposer.org](http://getcomposer.org/).
+
+## Running tests
+
+tumblr.php has full unit tests that can be run with PHPUnit like this:
+
+``` bash
+$ phpunit
+```
+
+That will also generate a coverage report into `./coverage`
+
+## Copyright and license
+
+Copyright 2013 Tumblr, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this work except in compliance with the License. You may obtain a copy of
+the License in the LICENSE file, or at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations.
diff --git a/vendor/tumblr/tumblr/composer.json b/vendor/tumblr/tumblr/composer.json
new file mode 100644
index 0000000..748a16b
--- /dev/null
+++ b/vendor/tumblr/tumblr/composer.json
@@ -0,0 +1,39 @@
+{
+
+ "name": "tumblr/tumblr",
+
+ "description": "Official Tumblr PHP Client",
+
+ "keywords": ["tumblr", "api", "sdk", "gif"],
+
+ "homepage": "https://github.com/tumblr/tumblr.php",
+
+ "authors": [
+ {
+ "name": "John Crepezzi",
+ "email": "john.crepezzi@gmail.com",
+ "homepage": "https://github.com/seejohnrun",
+ "role": "developer"
+ }
+ ],
+
+ "license": "Apache-2.0",
+
+ "type": "library",
+
+ "require": {
+ "eher/oauth": "1.0.*",
+ "guzzlehttp/guzzle": "6.*"
+ },
+
+ "require-dev": {
+ "phpunit/phpunit": "5.3.*"
+ },
+
+ "autoload": {
+ "psr-0": {
+ "Tumblr\\API": "lib"
+ }
+ }
+
+}
diff --git a/vendor/tumblr/tumblr/lib/Tumblr/API/Client.php b/vendor/tumblr/tumblr/lib/Tumblr/API/Client.php
new file mode 100644
index 0000000..7d51138
--- /dev/null
+++ b/vendor/tumblr/tumblr/lib/Tumblr/API/Client.php
@@ -0,0 +1,502 @@
+<?php
+
+namespace Tumblr\API;
+
+/**
+ * A client to access the Tumblr API
+ */
+class Client
+{
+
+ private $apiKey;
+
+ /**
+ * Create a new Client
+ *
+ * @param string $consumerKey the consumer key
+ * @param string $consumerSecret the consumer secret
+ * @param string $token oauth token
+ * @param string $secret oauth token secret
+ */
+ public function __construct($consumerKey, $consumerSecret = null, $token = null, $secret = null)
+ {
+ $this->requestHandler = new RequestHandler();
+ $this->setConsumer($consumerKey, $consumerSecret);
+
+ if ($token && $secret) {
+ $this->setToken($token, $secret);
+ }
+ }
+
+ /**
+ * Set the consumer for this client
+ *
+ * @param string $consumerKey the consumer key
+ * @param string $consumerSecret the consumer secret
+ */
+ public function setConsumer($consumerKey, $consumerSecret)
+ {
+ $this->apiKey = $consumerKey;
+ $this->requestHandler->setConsumer($consumerKey, $consumerSecret);
+ }
+
+ /**
+ * Set the token for this client
+ *
+ * @param string $token the oauth token
+ * @param string $secret the oauth secret
+ */
+ public function setToken($token, $secret)
+ {
+ $this->requestHandler->setToken($token, $secret);
+ }
+
+ /**
+ * Retrieve RequestHandler instance
+ *
+ * @return RequestHandler
+ */
+ public function getRequestHandler()
+ {
+ return $this->requestHandler;
+ }
+
+ /**
+ * Get info on the authenticating user
+ *
+ * @return array the response array
+ */
+ public function getUserInfo()
+ {
+ return $this->getRequest('v2/user/info', null, false);
+ }
+
+ /**
+ * Get user dashboard for the authenticating user
+ *
+ * @param array $options the options for the call
+ * @return array the response array
+ */
+ public function getDashboardPosts($options = null)
+ {
+ return $this->getRequest('v2/user/dashboard', $options, false);
+ }
+
+ /**
+ * Get followings for the authenticating user
+ *
+ * @param array $options the options for the call
+ * @return array the response array
+ */
+ public function getFollowedBlogs($options = null)
+ {
+ return $this->getRequest('v2/user/following', $options, false);
+ }
+
+ /**
+ * Get likes for the authenticating user
+ *
+ * @param array $options the options for the call
+ * @return array the response array
+ */
+ public function getLikedPosts($options = null)
+ {
+ return $this->getRequest('v2/user/likes', $options, false);
+ }
+
+ /**
+ * Follow a blog
+ *
+ * @param string $blogName the name of the blog to follow
+ * @return array the response array
+ */
+ public function follow($blogName)
+ {
+ $options = array('url' => $this->blogUrl($blogName));
+
+ return $this->postRequest('v2/user/follow', $options, false);
+ }
+
+ /**
+ * Unfollow a blog
+ *
+ * @param string $blogName the name of the blog to follow
+ * @return array the response array
+ */
+ public function unfollow($blogName)
+ {
+ $options = array('url' => $this->blogUrl($blogName));
+
+ return $this->postRequest('v2/user/unfollow', $options, false);
+ }
+
+ /**
+ * Like a post
+ *
+ * @param int $postId the id of the post
+ * @param string $reblogKey the reblog_key of the post
+ *
+ * @return array the response array
+ */
+ public function like($postId, $reblogKey)
+ {
+ $options = array('id' => $postId, 'reblog_key' => $reblogKey);
+
+ return $this->postRequest('v2/user/like', $options, false);
+ }
+
+ /**
+ * Unlike a post
+ *
+ * @param int $postId the id of the post
+ * @param string $reblogKey the reblog_key of the post
+ *
+ * @return array the response array
+ */
+ public function unlike($postId, $reblogKey)
+ {
+ $options = array('id' => $postId, 'reblog_key' => $reblogKey);
+
+ return $this->postRequest('v2/user/unlike', $options, false);
+ }
+
+ /**
+ * Delete a post
+ *
+ * @param string $blogName the name of the blog the post is on
+ * @param int $postId the id of the post
+ * @param string $reblogKey the reblog_key of the post
+ *
+ * @return array the response array
+ */
+ public function deletePost($blogName, $postId, $reblogKey)
+ {
+ $options = array('id' => $postId, 'reblog_key' => $reblogKey);
+ $path = $this->blogPath($blogName, '/post/delete');
+
+ return $this->postRequest($path, $options, false);
+ }
+
+ /**
+ * Reblog a post
+ *
+ * @param string $blogName the name of the blog
+ * @param int $postId the id of the post
+ * @param string $reblogKey the reblog key of the post
+ * @param array $options the options for the call
+ *
+ * @return array the response array
+ */
+ public function reblogPost($blogName, $postId, $reblogKey, $options = null)
+ {
+ $params = array('id' => $postId, 'reblog_key' => $reblogKey);
+ $params = array_merge($options ?: array(), $params);
+ $path = $this->blogPath($blogName, '/post/reblog');
+
+ return $this->postRequest($path, $params, false);
+ }
+
+ /**
+ * Edit a post
+ *
+ * @param string $blogName the name of the blog
+ * @param int $postId the id of the post to edit
+ * @param array $data the data to save
+ *
+ * @return array the response array
+ */
+ public function editPost($blogName, $postId, $data)
+ {
+ $data['id'] = $postId;
+ $path = $this->blogPath($blogName, '/post/edit');
+
+ return $this->postRequest($path, $data, false);
+ }
+
+ /**
+ * Create a post
+ *
+ * @param string $blogName the name of the blog
+ * @param array $data the data to save
+ *
+ * @return array the response array
+ */
+ public function createPost($blogName, $data)
+ {
+ $path = $this->blogPath($blogName, '/post');
+
+ return $this->postRequest($path, $data, false);
+ }
+
+ /**
+ * Get tagged posts
+ *
+ * @param string $tag the tag to look up
+ * @param array $options the options for the call
+ *
+ * @return array the response array
+ */
+ public function getTaggedPosts($tag, $options = null)
+ {
+ if (!$options) {
+ $options = array();
+ }
+ $options['tag'] = $tag;
+
+ return $this->getRequest('v2/tagged', $options, true);
+ }
+
+ /**
+ * Get information about a given blog
+ *
+ * @param string $blogName the name of the blog to look up
+ * @return array the response array
+ */
+ public function getBlogInfo($blogName)
+ {
+ $path = $this->blogPath($blogName, '/info');
+
+ return $this->getRequest($path, null, true);
+ }
+
+ /**
+ * Get blog avatar URL
+ *
+ * @param string $blogName the nae of the blog to look up
+ * @param int $size the size to retrieve
+ *
+ * @return string the avatar url
+ */
+ public function getBlogAvatar($blogName, $size = null)
+ {
+ $path = $this->blogPath($blogName, '/avatar');
+ if ($size) {
+ $path .= "/$size";
+ }
+
+ return $this->getRedirect($path, null, true);
+ }
+
+ /**
+ * Get blog likes for a given blog
+ *
+ * @param string $blogName the name of the blog to look up
+ * @param array $options the options for the call
+ *
+ * @return array the response array
+ */
+ public function getBlogLikes($blogName, $options = null)
+ {
+ $path = $this->blogPath($blogName, '/likes');
+
+ return $this->getRequest($path, $options, true);
+ }
+
+ /**
+ * Get blog followers for a given blog
+ *
+ * @param string $blogName the name of the blog to look up
+ * @param array $options the options for the call
+ *
+ * @return array the response array
+ */
+ public function getBlogFollowers($blogName, $options = null)
+ {
+ $path = $this->blogPath($blogName, '/followers');
+
+ return $this->getRequest($path, $options, false);
+ }
+
+ /**
+ * Get posts for a given blog
+ *
+ * @param string $blogName the name of the blog
+ * @param array $options the options for the call
+ *
+ * @return array the response array
+ */
+ public function getBlogPosts($blogName, $options = null)
+ {
+ $path = $this->blogPath($blogName, '/posts');
+ if ($options && isset($options['type'])) {
+ $path .= '/' . $options['type'];
+ unset($options['type']);
+ }
+
+ return $this->getRequest($path, $options, true);
+ }
+
+ /**
+ * Get queue posts for a given blog
+ *
+ * @param string $blogName the name of the blog
+ * @param array $options the options for the call
+ *
+ * @return array the response array
+ */
+ public function getQueuedPosts($blogName, $options = null)
+ {
+ $path = $this->blogPath($blogName, '/posts/queue');
+
+ return $this->getRequest($path, $options, false);
+ }
+
+ /**
+ * Get draft posts for a given blog
+ *
+ * @param string $blogName the name of the blog
+ * @param array $options the options for the call
+ *
+ * @return array the response array
+ */
+ public function getDraftPosts($blogName, $options = null)
+ {
+ $path = $this->blogPath($blogName, '/posts/draft');
+
+ return $this->getRequest($path, $options, false);
+ }
+
+ /**
+ * Get submission posts for a given blog
+ *
+ * @param string $blogName the name of the blog
+ * @param array $options the options for the call
+ *
+ * @return array the response array
+ */
+ public function getSubmissionPosts($blogName, $options = null)
+ {
+ $path = $this->blogPath($blogName, '/posts/submission');
+
+ return $this->getRequest($path, $options, false);
+ }
+
+ /**
+ * Make a GET request to the given endpoint and return the response
+ *
+ * @param string $path the path to call on
+ * @param array $options the options to call with
+ * @param bool $addApiKey whether or not to add the api key
+ *
+ * @return array the response object (parsed)
+ */
+ public function getRequest($path, $options, $addApiKey)
+ {
+ $response = $this->makeRequest('GET', $path, $options, $addApiKey);
+
+ return $this->parseResponse($response);
+ }
+
+ /**
+ * Make a POST request to the given endpoint and return the response
+ *
+ * @param string $path the path to call on
+ * @param array $options the options to call with
+ * @param bool $addApiKey whether or not to add the api key
+ *
+ * @return array the response object (parsed)
+ */
+ public function postRequest($path, $options, $addApiKey)
+ {
+ if (isset($options['source']) && is_array($options['source'])) {
+ $sources = $options['source'];
+ unset($options['source']);
+ foreach ($sources as $i => $source) {
+ $options["source[$i]"] = $source;
+ }
+ }
+
+ $response = $this->makeRequest('POST', $path, $options, $addApiKey);
+ return $this->parseResponse($response);
+ }
+
+ /**
+ * Parse a response and return an appropriate result
+ *
+ * @param \stdClass $response the response from the server
+ *
+ * @throws RequestException
+ * @return array the response data
+ */
+ private function parseResponse($response)
+ {
+ $response->json = json_decode($response->body);
+ if ($response->status < 400) {
+ return $response->json->response;
+ } else {
+ throw new RequestException($response);
+ }
+ }
+
+ /**
+ * Make a GET request to the given endpoint and return the response
+ *
+ * @param string $path the path to call on
+ * @param array $options the options to call with
+ * @param bool $addApiKey whether or not to add the api key
+ *
+ * @return string url redirected to (or null)
+ */
+ private function getRedirect($path, $options, $addApiKey)
+ {
+ $response = $this->makeRequest('GET', $path, $options, $addApiKey);
+ if ($response->status === 301 || $response->status === 302) {
+ return $response->headers['Location'][0];
+ }
+
+ return null;
+ }
+
+ /**
+ * Make a request to the given endpoint and return the response
+ *
+ * @param string $method the method to call: GET, POST
+ * @param string $path the path to call on
+ * @param array $options the options to call with
+ * @param bool $addApiKey whether or not to add the api key
+ *
+ * @return \stdClass the response object (not parsed)
+ */
+ private function makeRequest($method, $path, $options, $addApiKey)
+ {
+ if ($addApiKey) {
+ $options = array_merge(
+ array('api_key' => $this->apiKey),
+ $options ?: array()
+ );
+ }
+
+ return $this->requestHandler->request($method, $path, $options);
+ }
+
+ /**
+ * Expand the given blogName into a base path for the blog
+ *
+ * @param string $blogName the name of the blog
+ * @param string $ext the url extension
+ *
+ * @return string the blog base path
+ */
+ private function blogPath($blogName, $ext)
+ {
+ $blogUrl = $this->blogUrl($blogName);
+
+ return "v2/blog/$blogUrl$ext";
+ }
+
+ /**
+ * Get the URL of a blog by name or URL
+ *
+ * @param string $blogName the name of the blog
+ * @return string the blog URL
+ */
+ private function blogUrl($blogName)
+ {
+ if (strpos($blogName, '.') === false) {
+ return "$blogName.tumblr.com";
+ }
+
+ return $blogName;
+ }
+
+}
diff --git a/vendor/tumblr/tumblr/lib/Tumblr/API/RequestException.php b/vendor/tumblr/tumblr/lib/Tumblr/API/RequestException.php
new file mode 100644
index 0000000..00af04b
--- /dev/null
+++ b/vendor/tumblr/tumblr/lib/Tumblr/API/RequestException.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Tumblr\API;
+
+class RequestException extends \Exception
+{
+
+ /**
+ * @param \stdClass $response
+ */
+ public function __construct($response)
+ {
+ $error = json_decode($response->body);
+
+ $errstr = 'Unknown Error';
+ if (isset($error->meta)) {
+ $errstr = $error->meta->msg;
+ if (isset($error->response->errors)) {
+ $errstr .= ' ('.$error->response->errors[0].')';
+ }
+ } elseif (isset($error->response->errors)) {
+ $errstr = $error->response->errors[0];
+ }
+
+ $this->statusCode = $response->status;
+ $this->message = $errstr;
+ parent::__construct($this->message, $this->statusCode);
+ }
+
+ public function __toString()
+ {
+ return __CLASS__ . ": [$this->statusCode]: $this->message\n";
+ }
+
+}
diff --git a/vendor/tumblr/tumblr/lib/Tumblr/API/RequestHandler.php b/vendor/tumblr/tumblr/lib/Tumblr/API/RequestHandler.php
new file mode 100644
index 0000000..c14eefc
--- /dev/null
+++ b/vendor/tumblr/tumblr/lib/Tumblr/API/RequestHandler.php
@@ -0,0 +1,151 @@
+<?php
+
+namespace Tumblr\API;
+
+/**
+ * A request handler for Tumblr authentication
+ * and requests
+ */
+class RequestHandler
+{
+
+ private $consumer;
+ private $token;
+ private $signatureMethod;
+
+ private $baseUrl;
+ private $version;
+
+ /**
+ * Instantiate a new RequestHandler
+ */
+ public function __construct()
+ {
+ $this->baseUrl = 'https://api.tumblr.com/';
+ $this->version = '0.1.2';
+
+ $this->signatureMethod = new \Eher\OAuth\HmacSha1();
+ $this->client = new \GuzzleHttp\Client(array(
+ 'allow_redirects' => false,
+ ));
+ }
+
+ /**
+ * Set the consumer for this request handler
+ *
+ * @param string $key the consumer key
+ * @param string $secret the consumer secret
+ */
+ public function setConsumer($key, $secret)
+ {
+ $this->consumer = new \Eher\OAuth\Consumer($key, $secret);
+ }
+
+ /**
+ * Set the token for this request handler
+ *
+ * @param string $token the oauth token
+ * @param string $secret the oauth secret
+ */
+ public function setToken($token, $secret)
+ {
+ $this->token = new \Eher\OAuth\Token($token, $secret);
+ }
+
+ /**
+ * Set the base url for this request handler.
+ *
+ * @param string $url The base url (e.g. https://api.tumblr.com)
+ */
+ public function setBaseUrl($url)
+ {
+ // Ensure we have a trailing slash since it is expected in {@link request}.
+ if (substr($url, -1) !== '/') {
+ $url .= '/';
+ }
+
+ $this->baseUrl = $url;
+ }
+
+ /**
+ * Make a request with this request handler
+ *
+ * @param string $method one of GET, POST
+ * @param string $path the path to hit
+ * @param array $options the array of params
+ *
+ * @return \stdClass response object
+ */
+ public function request($method, $path, $options)
+ {
+ // Ensure we have options
+ $options = $options ?: array();
+
+ // Take off the data param, we'll add it back after signing
+ $file = isset($options['data']) ? $options['data'] : false;
+ unset($options['data']);
+
+ // Get the oauth signature to put in the request header
+ $url = $this->baseUrl . $path;
+ $oauth = \Eher\OAuth\Request::from_consumer_and_token(
+ $this->consumer,
+ $this->token,
+ $method,
+ $url,
+ $options
+ );
+ $oauth->sign_request($this->signatureMethod, $this->consumer, $this->token);
+ $authHeader = $oauth->to_header();
+ $pieces = explode(' ', $authHeader, 2);
+ $authString = $pieces[1];
+
+
+ // Set up the request and get the response
+ $uri = new \GuzzleHttp\Psr7\Uri($url);
+ $guzzleOptions = [
+ 'headers' => [
+ 'Authorization' => $authString,
+ 'User-Agent' => 'tumblr.php/' . $this->version,
+ ],
+ // Swallow exceptions since \Tumblr\API\Client will handle them
+ 'http_errors' => false,
+ ];
+ if ($method === 'GET') {
+ $uri = $uri->withQuery(http_build_query($options));
+ } elseif ($method === 'POST') {
+ if (!$file) {
+ $guzzleOptions['form_params'] = $options;
+ } else {
+ // Add the files back now that we have the signature without them
+ $content_type = 'multipart';
+ $form = [];
+ foreach ($options as $name => $contents) {
+ $form[] = [
+ 'name' => $name,
+ 'contents' => $contents,
+ ];
+ }
+ foreach ((array) $file as $idx => $path) {
+ $form[] = [
+ 'name' => "data[$idx]",
+ 'contents' => file_get_contents($path),
+ 'filename' => pathinfo($path, PATHINFO_FILENAME),
+ ];
+ }
+ $guzzleOptions['multipart'] = $form;
+ }
+ }
+
+ $response = $this->client->request($method, $uri, $guzzleOptions);
+
+ // Construct the object that the Client expects to see, and return it
+ $obj = new \stdClass;
+ $obj->status = $response->getStatusCode();
+ // Turn the stream into a string
+ $obj->body = $response->getBody()->__toString();
+ $obj->headers = $response->getHeaders();
+
+ return $obj;
+ }
+
+}
diff --git a/vendor/tumblr/tumblr/phpunit.xml b/vendor/tumblr/tumblr/phpunit.xml
new file mode 100644
index 0000000..2e7968c
--- /dev/null
+++ b/vendor/tumblr/tumblr/phpunit.xml
@@ -0,0 +1,15 @@
+<phpunit bootstrap="test/bootstrap.php" colors="true">
+ <testsuites>
+ <testsuite name="Tumblr SDK for PHP - Test Suite">
+ <directory>test</directory>
+ </testsuite>
+ </testsuites>
+ <filter>
+ <whitelist>
+ <directory suffix=".php">lib</directory>
+ </whitelist>
+ </filter>
+ <logging>
+ <log type="coverage-html" target="./coverage" highlight="true"/>
+ </logging>
+</phpunit>
diff --git a/vendor/tumblr/tumblr/test/BlogTest.php b/vendor/tumblr/tumblr/test/BlogTest.php
new file mode 100644
index 0000000..22a63bf
--- /dev/null
+++ b/vendor/tumblr/tumblr/test/BlogTest.php
@@ -0,0 +1,67 @@
+<?php
+
+class BlogTest extends TumblrTest
+{
+ public function providerCalls()
+ {
+ $test = $this; // for inner context
+
+ return array(
+
+ // getBlogInfo
+ array(function ($c) { $c->getBlogInfo('b'); }, 'GET', 'v2/blog/b.tumblr.com/info', array('api_key' => API_KEY)),
+
+ // getBlogAvatar
+ array(function ($c) use ($test) {
+ $url = $c->getBlogAvatar('b');
+ $test->assertEquals($url, 'url');
+ }, 'GET', 'v2/blog/b.tumblr.com/avatar', array('api_key' => API_KEY), 'redirect'),
+ array(function ($c) use ($test) {
+ $url = $c->getBlogAvatar('b');
+ $test->assertEquals($url, null);
+ }, 'GET', 'v2/blog/b.tumblr.com/avatar', array('api_key' => API_KEY), 'not_found'),
+ array(function ($c) { $c->getBlogAvatar('b', 128); }, 'GET', 'v2/blog/b.tumblr.com/avatar/128', array('api_key' => API_KEY)),
+
+ // getBlogLikes
+ array(function ($c) { $c->getBlogLikes('b.n'); }, 'GET', 'v2/blog/b.n/likes', array('api_key' => API_KEY)),
+ array(function ($c) { $c->getBlogLikes('b.n', array('limit' => 10)); }, 'GET', 'v2/blog/b.n/likes', array('limit' => 10, 'api_key' => API_KEY)),
+
+ // getBlogFollowers
+ array(function ($c) { $c->getBlogFollowers('b.n'); }, 'GET', 'v2/blog/b.n/followers', null),
+ array(function ($c) { $c->getBlogFollowers('b.n', array('limit' => 10)); }, 'GET', 'v2/blog/b.n/followers', array('limit' => 10)),
+
+ // getBlogPosts
+ array(function ($c) { $c->getBlogPosts('b.n'); }, 'GET', 'v2/blog/b.n/posts', array('api_key' => API_KEY)),
+ array(function ($c) { $c->getBlogPosts('b.n', array('limit' => 10)); }, 'GET', 'v2/blog/b.n/posts', array('limit' => 10, 'api_key' => API_KEY)),
+ array(function ($c) { $c->getBlogPosts('b.n', array('type' => 'text')); }, 'GET', 'v2/blog/b.n/posts/text', array('api_key' => API_KEY)),
+
+ // getQueuedPosts
+ array(function ($c) { $c->getQueuedPosts('b.n'); }, 'GET', 'v2/blog/b.n/posts/queue', null),
+ array(function ($c) { $c->getQueuedPosts('b.n', array('limit' => 10)); }, 'GET', 'v2/blog/b.n/posts/queue', array('limit' => 10)),
+
+ // getDraftPosts
+ array(function ($c) { $c->getDraftPosts('b.n'); }, 'GET', 'v2/blog/b.n/posts/draft', null),
+ array(function ($c) { $c->getDraftPosts('b.n', array('limit' => 10)); }, 'GET', 'v2/blog/b.n/posts/draft', array('limit' => 10)),
+
+ // getSubmissionPosts
+ array(function ($c) { $c->getSubmissionPosts('b.n'); }, 'GET', 'v2/blog/b.n/posts/submission', null),
+ array(function ($c) { $c->getSubmissionPosts('b.n', array('limit' => 10)); }, 'GET', 'v2/blog/b.n/posts/submission', array('limit' => 10)),
+
+ );
+ }
+
+ public function testNotFound()
+ {
+ try {
+ $this->testCalls(function ($c) {
+ $c->getBlogInfo('b');
+ }, 'GET', 'v2/blog/b.tumblr.com/info', array('api_key' => API_KEY), 'not_found');
+ } catch (\Tumblr\API\RequestException $e) {
+ $this->assertEquals((string) $e, "Tumblr\API\RequestException: [404]: Unknown Error\n");
+
+ return;
+ }
+ $this->fail('no error thrown');
+ }
+
+}
diff --git a/vendor/tumblr/tumblr/test/PostTest.php b/vendor/tumblr/tumblr/test/PostTest.php
new file mode 100644
index 0000000..55d1bdb
--- /dev/null
+++ b/vendor/tumblr/tumblr/test/PostTest.php
@@ -0,0 +1,30 @@
+<?php
+
+class PostTest extends TumblrTest
+{
+ public function providerCalls()
+ {
+ return array(
+
+ // delete post
+ array(function ($c) { $c->deletePost('b', 123, 'abc'); }, 'POST', 'v2/blog/b.tumblr.com/post/delete', array('id' => 123, 'reblog_key' => 'abc')),
+
+ // reblog post
+ array(function ($c) { $c->reblogPost('b', 123, 'abc'); }, 'POST', 'v2/blog/b.tumblr.com/post/reblog', array('id' => 123, 'reblog_key' => 'abc')),
+ array(function ($c) { $c->reblogPost('b', 123, 'abc', array('something' => 'else')); }, 'POST', 'v2/blog/b.tumblr.com/post/reblog', array('id' => 123, 'reblog_key' => 'abc', 'something' => 'else')),
+
+ // edit post
+ array(function ($c) { $c->editPost('b.n', 123, array('d' => 'ata')); }, 'POST', 'v2/blog/b.n/post/edit', array('d' => 'ata', 'id' => 123)),
+
+ // create post
+ array(function ($c) { $c->createPost('b.n', array('d' => 'ata')); }, 'POST', 'v2/blog/b.n/post', array('d' => 'ata')),
+
+ // single source
+ array(function ($c) { $c->createPost('b.n', array('source' => 'remote')); }, 'POST', 'v2/blog/b.n/post', array('source' => 'remote')),
+
+ // multi-source
+ array(function ($c) { $c->createPost('b.n', array('source' => array('r1', 'r2'))); }, 'POST', 'v2/blog/b.n/post', array('source[0]' => 'r1', 'source[1]' => 'r2')),
+
+ );
+ }
+}
diff --git a/vendor/tumblr/tumblr/test/RequestExceptionTest.php b/vendor/tumblr/tumblr/test/RequestExceptionTest.php
new file mode 100644
index 0000000..6180bca
--- /dev/null
+++ b/vendor/tumblr/tumblr/test/RequestExceptionTest.php
@@ -0,0 +1,28 @@
+<?php
+
+class RequestExceptionTest extends PHPUnit_Framework_TestCase
+{
+ public function provider()
+ {
+ $class_name = 'Tumblr\API\RequestException';
+
+ return array(
+
+ array(array('status' => 401, 'body' => '{}'), "$class_name: [401]: Unknown Error\n"),
+
+ array(array('status' => 404, 'body' => '{"meta":{"msg":"cool story bro"}}'), "$class_name: [404]: cool story bro\n"),
+
+ );
+ }
+
+ /**
+ * @dataProvider provider
+ */
+ public function testErrorString($responseArr, $expectedString)
+ {
+ $response = (object) $responseArr;
+ $err = new \Tumblr\API\RequestException($response);
+ $this->assertEquals((string) $err, $expectedString);
+ }
+
+}
diff --git a/vendor/tumblr/tumblr/test/RequestHandlerTest.php b/vendor/tumblr/tumblr/test/RequestHandlerTest.php
new file mode 100644
index 0000000..4dfdcb9
--- /dev/null
+++ b/vendor/tumblr/tumblr/test/RequestHandlerTest.php
@@ -0,0 +1,71 @@
+<?php
+
+class RequestHandlerTest extends \PHPUnit_Framework_TestCase
+{
+ public function testBaseUrlHasTrailingSlash()
+ {
+ $client = new Tumblr\API\Client(API_KEY);
+ $rh = $client->getRequestHandler();
+ $this->assertInstanceOf('Tumblr\API\RequestHandler', $rh);
+
+ $rh->setBaseUrl('http://example.com');
+ $this->assertAttributeEquals('http://example.com/', 'baseUrl', $rh);
+
+ $rh->setBaseUrl('http://example.com/');
+ $this->assertAttributeEquals('http://example.com/', 'baseUrl', $rh);
+ }
+
+ /**
+ * @expectedException GuzzleHttp\Exception\ConnectException
+ */
+ public function testRequestThrowsErrorOnMalformedBaseUrl()
+ {
+ $client = new Tumblr\API\Client(API_KEY);
+ $rh = $client->getRequestHandler();
+ $rh->setBaseUrl('this is a malformed URL!');
+
+ $options = array('some kinda option');
+
+ $rh->request('GET', 'foo', $options);
+
+ }
+
+ /**
+ * @expectedException Tumblr\API\RequestException
+ * @expectedExceptionCode 400
+ * @expectedExceptionMessage Sadface
+ */
+ public function testRequestThrowsOnBadResponse()
+ {
+ // Setup mock handler and response
+ $mock = new GuzzleHttp\Handler\MockHandler([
+ new GuzzleHttp\Psr7\Response(400, [], '{"meta": {"status": 400, "msg": "Sadface"} }'),
+ ]);
+ $stack = GuzzleHttp\HandlerStack::create($mock);
+ $guzzle = new GuzzleHttp\Client(['handler' => $stack]);
+
+ // Attached mocked guzzle client
+ $client = new Tumblr\API\Client(API_KEY);
+ $client->getRequestHandler()->client = $guzzle;
+
+ // Throws because it got a 400 back
+ $client->getBlogInfo('ceyko.tumblr.com');
+ }
+
+ public function testRequestGetsJsonResponseField()
+ {
+ // Setup mock handler and response
+ $mock = new GuzzleHttp\Handler\MockHandler([
+ new GuzzleHttp\Psr7\Response(200, [], '{"meta": {"status": 200, "msg": "OK"}, "response": "Response Text"}'),
+ ]);
+ $stack = GuzzleHttp\HandlerStack::create($mock);
+ $guzzle = new GuzzleHttp\Client(['handler' => $stack]);
+
+ // Attached mocked guzzle client
+ $client = new Tumblr\API\Client(API_KEY);
+ $client->getRequestHandler()->client = $guzzle;
+
+ // Parses out the `reponse` field in json on success
+ $this->assertEquals($client->getBlogInfo('ceyko.tumblr.com'), 'Response Text');
+ }
+}
diff --git a/vendor/tumblr/tumblr/test/TaggedTest.php b/vendor/tumblr/tumblr/test/TaggedTest.php
new file mode 100644
index 0000000..c595508
--- /dev/null
+++ b/vendor/tumblr/tumblr/test/TaggedTest.php
@@ -0,0 +1,16 @@
+<?php
+
+class TaggedTest extends TumblrTest
+{
+ public function providerCalls()
+ {
+ return array(
+
+ // getTaggedPosts
+ array(function ($c) { $c->getTaggedPosts('hey'); }, 'GET', 'v2/tagged', array('tag' => 'hey', 'api_key' => API_KEY)),
+ array(function ($c) { $c->getTaggedPosts('hey', array('limit' => 10)); }, 'GET', 'v2/tagged', array('limit' => 10, 'tag' => 'hey', 'api_key' => API_KEY)),
+
+ );
+ }
+
+}
diff --git a/vendor/tumblr/tumblr/test/TumblrTest.php b/vendor/tumblr/tumblr/test/TumblrTest.php
new file mode 100644
index 0000000..a014634
--- /dev/null
+++ b/vendor/tumblr/tumblr/test/TumblrTest.php
@@ -0,0 +1,51 @@
+<?php
+
+class TumblrTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider providerCalls
+ */
+ public function testCalls($callable, $type, $path, $params, $which_mock = 'perfect')
+ {
+ // a good response
+ $response = $this->getResponseMock($which_mock);
+
+ // Create request mock and set it to check for the proper response
+ $request = $this->getMock('Tumblr\API\RequestHandler', array('request'));
+ $request->expects($this->once())
+ ->method('request')
+ ->with($this->equalTo($type), $this->equalTo($path), $this->equalTo($params))
+ ->will($this->returnValue($response));
+
+ // Create a new client and set it up to use that request handler
+ $client = new Tumblr\API\Client(API_KEY);
+ $ref = new ReflectionObject($client);
+ $prop = $ref->getProperty('requestHandler');
+ $prop->setAccessible(true);
+ $prop->setValue($client, $request);
+
+ // Give it tokens
+ $client->setToken('t1', 't2');
+
+ // And then run the callback to check the results
+ $callable($client);
+ }
+
+ private function getResponseMock($which)
+ {
+ $response = new stdClass;
+ if ($which == 'perfect') {
+ $response->status = 200;
+ $response->body = '{"response":[]}';
+ } elseif ($which == 'redirect') {
+ $response->status = 301;
+ $response->headers = array('Location' => array('url'));
+ } elseif ($which == 'not_found') {
+ $response->status = 404;
+ $response->body = '{}';
+ }
+
+ return $response;
+ }
+
+}
diff --git a/vendor/tumblr/tumblr/test/UserTest.php b/vendor/tumblr/tumblr/test/UserTest.php
new file mode 100644
index 0000000..e42b336
--- /dev/null
+++ b/vendor/tumblr/tumblr/test/UserTest.php
@@ -0,0 +1,40 @@
+<?php
+
+class UserTest extends TumblrTest
+{
+ public function providerCalls()
+ {
+ return array(
+
+ // getUserInfo
+ array(function ($c) { $c->getUserInfo(); }, 'GET', 'v2/user/info', null),
+
+ // getDashboardPosts
+ array(function ($c) { $c->getDashboardPosts(); }, 'GET', 'v2/user/dashboard', null),
+ array(function ($c) { $c->getDashboardPosts(array('limit' => 10)); }, 'GET', 'v2/user/dashboard', array('limit' => 10)),
+
+ // getFollowedBlogs
+ array(function ($c) { $c->getFollowedBlogs(); }, 'GET', 'v2/user/following', null),
+ array(function ($c) { $c->getFollowedBlogs(array('limit' => 10)); }, 'GET', 'v2/user/following', array('limit' => 10)),
+
+ // getLikedPosts
+ array(function ($c) { $c->getLikedPosts(); }, 'GET', 'v2/user/likes', null),
+ array(function ($c) { $c->getLikedPosts(array('limit' => 10)); }, 'GET', 'v2/user/likes', array('limit' => 10)),
+
+ // follow
+ array(function ($c) { $c->follow('b'); }, 'POST', 'v2/user/follow', array('url' => 'b.tumblr.com')),
+ array(function ($c) { $c->follow('b.n'); }, 'POST', 'v2/user/follow', array('url' => 'b.n')),
+
+ // unfollow
+ array(function ($c) { $c->unfollow('b'); }, 'POST', 'v2/user/unfollow', array('url' => 'b.tumblr.com')),
+
+ // like
+ array(function ($c) { $c->like(123, 'abc'); }, 'POST', 'v2/user/like', array('id' => 123, 'reblog_key' => 'abc')),
+
+ // unlike
+ array(function ($c) { $c->unlike(123, 'abc'); }, 'POST', 'v2/user/unlike', array('id' => 123, 'reblog_key' => 'abc')),
+
+ );
+ }
+
+}
diff --git a/vendor/tumblr/tumblr/test/bootstrap.php b/vendor/tumblr/tumblr/test/bootstrap.php
new file mode 100644
index 0000000..cfa1b00
--- /dev/null
+++ b/vendor/tumblr/tumblr/test/bootstrap.php
@@ -0,0 +1,8 @@
+<?php
+
+date_default_timezone_set('America/New_York');
+
+require_once 'vendor/autoload.php';
+require_once 'test/TumblrTest.php';
+
+define('API_KEY', 'the testing consumer key');