From 7c20ef7884f6a9bf61d680ef57a12d8fb0cf2f57 Mon Sep 17 00:00:00 2001 From: weryques Date: Wed, 29 Nov 2017 11:45:30 -0200 Subject: [PATCH] API, API Tests and Setup Doc. Added API Tests, Added API Endpoints, Documentation modified --- .gitignore | 1 - composer.json | 3 +- composer.lock | 237 +----------------- docs/setup-local.md | 23 +- ...s-tainacan-rest-collections-controller.php | 112 ++++++++- .../entities/class-tainacan-collection.php | 1 + .../repositories/class-tainacan-items.php | 2 +- src/tainacan.php | 63 +---- tests/bin/install-wp-tests.sh | 15 +- tests/test-api-collections.php | 49 ++-- 10 files changed, 166 insertions(+), 340 deletions(-) diff --git a/.gitignore b/.gitignore index 017504084..995bc48be 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,3 @@ tests/bootstrap-config.php .settings vendor src/vendor - diff --git a/composer.json b/composer.json index 700c8ea35..e1a34004c 100644 --- a/composer.json +++ b/composer.json @@ -3,8 +3,7 @@ "description": "Protótipo", "type": "wordpress-plugin", "require": { - "respect/validation": "^1.1", - "guzzlehttp/guzzle": "^6.2@dev" + "respect/validation": "^1.1" }, "minimum-stability": "dev", "config": { diff --git a/composer.lock b/composer.lock index a95c05091..21706ee0d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,239 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "06908e8219e421f4b636b0159525e648", + "content-hash": "e0eb272f68b3132a64ef299d34cf9700", "packages": [ - { - "name": "guzzlehttp/guzzle", - "version": "6.3.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699", - "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699", - "shasum": "" - }, - "require": { - "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.4", - "php": ">=5.5" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "^4.0 || ^5.0", - "psr/log": "^1.0" - }, - "suggest": { - "psr/log": "Required for using the Log middleware" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.2-dev" - } - }, - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "time": "2017-06-22T18:50:49+00:00" - }, - { - "name": "guzzlehttp/promises", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "e9cdab6ff93ff789b5b599326c727f51d10893a6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/e9cdab6ff93ff789b5b599326c727f51d10893a6", - "reference": "e9cdab6ff93ff789b5b599326c727f51d10893a6", - "shasum": "" - }, - "require": { - "php": ">=5.5.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.36" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ], - "time": "2017-10-06T12:25:00+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "d2537c86fa8b004c29e9b9f5e10028f0a29df101" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/d2537c86fa8b004c29e9b9f5e10028f0a29df101", - "reference": "d2537c86fa8b004c29e9b9f5e10028f0a29df101", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Schultze", - "homepage": "https://github.com/Tobion" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "request", - "response", - "stream", - "uri", - "url" - ], - "time": "2017-10-07T03:19:56+00:00" - }, - { - "name": "psr/http-message", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "time": "2016-08-06T14:39:51+00:00" - }, { "name": "respect/validation", "version": "1.1.x-dev", @@ -365,9 +134,7 @@ "packages-dev": [], "aliases": [], "minimum-stability": "dev", - "stability-flags": { - "guzzlehttp/guzzle": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": [], diff --git a/docs/setup-local.md b/docs/setup-local.md index 175015333..17ec05bf0 100644 --- a/docs/setup-local.md +++ b/docs/setup-local.md @@ -63,20 +63,37 @@ Create a new MySQL database for your tests. This database will be cleaned and re Install the WordPress Tests library running the provided script. ``` -tests/bin/install-wp-tests.sh wordpress_test root '' localhost latest +tests/bin/install-wp-tests.sh wordpress_test root root /path/to/webserver/document/root localhost latest ``` The parameters are: * Database name * MySQL username * MySQL password +* Test Directory (This should be your web server document root) * MySQL host * WordPress version -By default, this script installs a copy of WordPress in your /tmp folder. If you want to install it in a different location, edit the file and run it again. (TODO: make a config for that). - Inside `tests` folder, edit the file called `bootstrap-config-sample.php` and inform the folder where you installed your WordPress Test Library. Save the file as `bootstrap-config.php`. +##### To test the API + +Go to the `wordpress-test-lib` directory located in your test directory, open the file `wordpress-tests-config.php` and change the (could be different) with your configs, like the following: + +``` +define( 'WP_TESTS_DOMAIN', '/wordpress-test/' ); +define( 'WP_TESTS_EMAIL', 'test@' ); +define( 'WP_TESTS_TITLE', 'Tainacan Tests' ); +``` + +With it done, go to `wordpress-test` directory. Make a copy of the `wp-config-sample.php` to `wp-config.php`, open that new file and add the MySQL settings, which you informed on installation script. + +Now go to the URL of the wordpress installation test (example: localhost/wordpress-test) and make the wordpress common installation. + +Execute the build script, go to Wordpress plugins page and active Tainacan plugin. + +Obs: Don't forget, the URL used in API tests should be the same in constant `WP_TESTS_DOMAIN`, of course, with the prefix `http://` (like http://localhost/wordpress-test/). + You are done! Now, to run your tests, simply go to the root directory of the repository and type: ``` diff --git a/src/api/endpoints/class-tainacan-rest-collections-controller.php b/src/api/endpoints/class-tainacan-rest-collections-controller.php index 3710c290a..dcb3cc693 100644 --- a/src/api/endpoints/class-tainacan-rest-collections-controller.php +++ b/src/api/endpoints/class-tainacan-rest-collections-controller.php @@ -1,14 +1,17 @@ namespace = 'tainacan/v2'; $this->rest_base = 'collections'; - $this->collections_respository = new Repositories\Collections(); + $this->collections_repository = new Repositories\Collections(); + $this->collection = new Entities\Collection(); add_action('rest_api_init', array($this, 'register_routes')); } @@ -18,20 +21,38 @@ class TAINACAN_REST_Collections_Controller extends WP_REST_Controller { array( 'methods' => WP_REST_Server::READABLE, 'callback' => array($this, 'get_items'), - //'permission_callback' => array($this, 'get_items_permission_check'), + 'permission_callback' => array($this, 'get_items_permissions_check'), + 'args' => $this->get_collection_params(), ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array($this, 'create_item'), + 'permission_callback' => array($this, 'create_item_permissions_check'), + 'args' => $this->get_endpoint_args_for_item_schema(WP_REST_Server::CREATABLE), + ), + 'schema' => array($this, 'get_public_item_schema'), )); register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array($this, 'get_item'), - //'permission_callback' => array($this, 'get_item_permission_check'), + 'methods' => WP_REST_Server::READABLE, + 'callback' => array($this, 'get_item'), + 'permission_callback' => array($this, 'get_item_permissions_check'), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array($this, 'update_item'), + 'permission_callback' => array($this, 'update_item_permissions_check'), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array($this, 'delete_item'), + 'permission_callback' => array($this, 'delete_item_permissions_check'), ), )); } public function get_items($request){ - $collections = $this->collections_respository->fetch(); + $collections = $this->collections_repository->fetch(); $response = $this->prepare_item_for_response($collections, $request); @@ -40,7 +61,7 @@ class TAINACAN_REST_Collections_Controller extends WP_REST_Controller { public function get_item($request){ $collection_id = $request['id']; - $collection = $this->collections_respository->fetch($collection_id); + $collection = $this->collections_repository->fetch($collection_id); $response = $this->prepare_item_for_response($collection, $request); @@ -52,10 +73,10 @@ class TAINACAN_REST_Collections_Controller extends WP_REST_Controller { $collections_as_json = []; foreach ($item as $wp_post){ - array_push($posts_as_json, $wp_post->__toJSON()); + array_push($collections_as_json, $wp_post->__toJSON()); } - return $collections_as_json; + return json_encode($collections_as_json); } else { return $item->__toJSON(); @@ -67,12 +88,77 @@ class TAINACAN_REST_Collections_Controller extends WP_REST_Controller { } public function get_items_permissions_check($request){ - return parent::get_items_permissions_check($request); // TODO: Change the autogenerated stub + return true; } public function get_item_permissions_check($request){ - return parent::get_item_permissions_check($request); // TODO: Change the autogenerated stub + return true; + } + + public function create_item( $request ) { + $request = json_decode($request->get_body(), true); + + if (!empty($request['id'])){ + return new WP_Error( 'rest_post_exists', __( 'Cannot create existing post.' ), array( 'status' => 400 ) ); + } + + $prepared_post = $this->prepare_item_for_database($request); + + if($prepared_post->validate()) { + $collection = $this->collections_repository->insert( $prepared_post ); + + return new WP_REST_Response($collection->__toJSON(), 200); + } + + return $prepared_post->get_errors(); + } + + public function create_item_permissions_check( $request ) { + //if(current_user_can('edit_posts')){ + return true; + //} + } + + public function prepare_item_for_database( $request ) { + $this->collection->set_name($request['name']); + $this->collection->set_description($request['description']); + + return $this->collection; + } + + public function delete_item( $request ) { + return parent::delete_item( $request ); // TODO: Change the autogenerated stub + } + + public function delete_item_permissions_check( $request ) { + if(current_user_can('delete_posts')){ + return true; + } + } + + public function update_item( $request ) { + return parent::update_item( $request ); // TODO: Change the autogenerated stub + } + + public function update_item_permissions_check( $request ) { + if(current_user_can('edit_posts')){ + return true; + } + } + + public function get_public_item_schema() { + return parent::get_public_item_schema(); // TODO: Change the autogenerated stub + } + + public function get_collection_params() { + $query_params = $this->collections_repository->get_map(); + + return apply_filters("rest_{$this->collection->get_post_type()}_collection_params", $query_params, $this->collection->get_post_type()); + } + + public function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) { + return parent::get_endpoint_args_for_item_schema( $method ); // TODO: Change the autogenerated stub } } -?> \ No newline at end of file +?> diff --git a/src/classes/entities/class-tainacan-collection.php b/src/classes/entities/class-tainacan-collection.php index 115c60d94..246d27572 100644 --- a/src/classes/entities/class-tainacan-collection.php +++ b/src/classes/entities/class-tainacan-collection.php @@ -38,6 +38,7 @@ class Collection extends Entity { public function __toJSON(){ return json_encode( [ + 'id' => $this->get_id(), 'name' => $this->get_name(), 'description' => $this->get_description(), ], diff --git a/src/classes/repositories/class-tainacan-items.php b/src/classes/repositories/class-tainacan-items.php index ef8d926c9..9c85494c6 100644 --- a/src/classes/repositories/class-tainacan-items.php +++ b/src/classes/repositories/class-tainacan-items.php @@ -43,7 +43,7 @@ class Items extends Repository { // register collections post type and associate taxonomies foreach ($collections as $collection) { - $collection->register_post_type(); + $collection->register_collection_item_post_type(); } // register taxonomies diff --git a/src/tainacan.php b/src/tainacan.php index b776414f4..ad9030197 100644 --- a/src/tainacan.php +++ b/src/tainacan.php @@ -1,11 +1,11 @@ add(), find(), get() - * - * $collection->getItems(), getItem(), addItem(), deleteItem() - * - * metadados registrado via codigo deinem ibase_add_user - * colecoes registradas via cõdigo passam o objeto inteiro e marcamos de algum jeito q não são editaveis - * (source) - * - * - */ - - function tnc_enable_dev_wp_interface() { return defined('TNC_ENABLE_DEV_WP_INTERFACE') && true === TNC_ENABLE_DEV_WP_INTERFACE ? true : false; -} \ No newline at end of file +} diff --git a/tests/bin/install-wp-tests.sh b/tests/bin/install-wp-tests.sh index 73bb4c787..d2fde0e38 100755 --- a/tests/bin/install-wp-tests.sh +++ b/tests/bin/install-wp-tests.sh @@ -1,19 +1,18 @@ #!/usr/bin/env bash -if [ $# -lt 3 ]; then - echo "usage: $0 [db-host] [wp-version] [skip-database-creation]" +if [ $# -lt 5 ]; then + echo "usage: $0 [db-host] [wp-version] [skip-database-creation]" exit 1 fi DB_NAME=$1 DB_USER=$2 DB_PASS=$3 -DB_HOST=${4-localhost} -WP_VERSION=${5-latest} -SKIP_DB_CREATE=${6-false} - -WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} -WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} +WP_TESTS_DIR=$4/wordpress-tests-lib +WP_CORE_DIR=$4/wordpress-test +DB_HOST=${5-localhost} +WP_VERSION=${6-latest} +SKIP_DB_CREATE=${7-false} download() { if [ `which curl` ]; then diff --git a/tests/test-api-collections.php b/tests/test-api-collections.php index ea3ccb36d..a3aba2172 100644 --- a/tests/test-api-collections.php +++ b/tests/test-api-collections.php @@ -2,37 +2,46 @@ namespace Tainacan\Tests; -use \GuzzleHttp\Client; +class TAINACAN_REST_Collections_Controller extends \WP_UnitTestCase { + const URL = 'http://localhost/wordpress-test/'; -class TAINACAN_REST_Collections_Controller extends \PHPUnit_Framework_TestCase { - protected $client; + public function test_create_and_fetch_collection_by_id(){ - const URL = 'http://localhost/wordpress/'; - - protected function setUp(){ - $this->client = new Client([ - 'base_uri' => self::URL, + $collection_JSON = json_encode([ + 'name' => 'Teste', + 'description' => 'Teste JSON', + 'itemsPerPage' => 10, ]); - } - public function test_fetch_collection_by_id(){ - $id = 1; - $response = $this->client->request('GET', 'wp-json/tainacan/v2/collections/'. $id); + $collection = wp_remote_post(self::URL . 'wp-json/tainacan/v2/collections/', array( + 'body' => $collection_JSON + )); - $this->assertEquals(200, $response->getStatusCode()); + $collection = json_decode(json_decode($collection['body'], true), true); - $data = json_decode(json_decode($response->getBody(), true)); - var_dump($data); - $this->assertEquals('teste', $data->name); + $id = $collection['id']; + + $response = wp_remote_get(self::URL . 'wp-json/tainacan/v2/collections/'. $id); + + $this->assertEquals(200, $response['response']['code']); + + $data = json_decode(json_decode($response['body'], true), true); + + $this->assertEquals('Teste', $data['name']); } public function test_fetch_collections(){ - $response = $this->client->request('GET', 'wp-json/tainacan/v2/collections/'); + $response = wp_remote_get(self::URL . 'wp-json/tainacan/v2/collections/'); - $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals(200, $response['response']['code']); - $data = json_decode($response->getBody(), true); - var_dump($data); + $data = json_decode(json_decode($response['body'], true), true); + + $this->assertContainsOnly('string', $data); + + $one_collection = json_decode($data[0], true); + + $this->assertEquals('Teste', $one_collection['name']); } }