API, API Tests and Setup Doc.

Added API Tests,
Added API Endpoints,
Documentation modified
This commit is contained in:
weryques 2017-11-29 11:45:30 -02:00
parent 9b02ecc101
commit 7c20ef7884
10 changed files with 166 additions and 340 deletions

1
.gitignore vendored
View File

@ -9,4 +9,3 @@ tests/bootstrap-config.php
.settings
vendor
src/vendor

View File

@ -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": {

237
composer.lock generated
View File

@ -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": [],

View File

@ -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 <domain-root> (could be different) with your configs, like the following:
```
define( 'WP_TESTS_DOMAIN', '<domain-root>/wordpress-test/' );
define( 'WP_TESTS_EMAIL', 'test@<domain-root>' );
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:
```

View File

@ -1,14 +1,17 @@
<?php
use Tainacan\Repositories;
use Tainacan\Entities;
class TAINACAN_REST_Collections_Controller extends WP_REST_Controller {
private $collections_respository;
private $collections_repository;
private $collection;
public function __construct(){
$this->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<id>[\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
}
}
?>
?>

View File

@ -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(),
],

View File

@ -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

View File

@ -1,11 +1,11 @@
<?php
/*
* Plugin Name: Tainacan
* Plugin URI: https://github.com/tainacan/tainacan
* Description: Transforme seu site Wordpress em um repositório digital
* Author: Media Lab / UFG
* Version: 1.0
Plugin Name: Tainacan
Plugin URI: https://github.com/tainacan/tainacan
Description: Transforme seu site Wordpress em um repositório digital
Author: Media Lab / UFG
Version: 1.0
*/
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
@ -16,57 +16,6 @@ const CLASSES_DIR = __DIR__ . '/classes/';
require_once(CLASSES_DIR . 'tainacan-creator.php');
require_once(API_DIR . 'tainacan-rest-creator.php');
/**
*
*
* nos loops instancia a Classes
*
* as classes no plural em repositories (talvez troccar esse nome pra não confundir)
* lidam com registro de post type, incialiação
* e tem o metodo find() pra busca, q usa o WP_Query, mas itera e substitui por objetos
* certos, talvez não precise instanciar na mão
* Nessas classes tb vão ter metodos, ativos se quisermos ver a interface dev padrao do WP
* q vai criar os metaboxes
* e tb os pre_get_posts...
*
*
*
* as classe em entities mapeiam suas propriedades para o esquema do WP, e não tem nenhuma lõgica,
* são objetos com propriedades, collection pode acessar seus metadados. item pode
* aessar sua coleção e metdados
* talvez ter um getter que tenta passar a propriedade buscada pra dentro da propriedade o objeto wp,
* usando o mapeamento ao contrãrio. assim um tema padrão não quebra
*
*
* Repository (não confundir) tem as opções gerais do repo, como o slug padrão das coisas (colecoes, item...)
*
* Vai no banco:
* Collections**
* Metadata
* Taxonomies
* Items**
* Filters
*
* ** Items e Collections vão aparecer na hierarquia de templates e podem ter loops
*
* $collections ou $items registra os post types das coleções?
*
* db_identifier das coleções não pode mudar, mesmo q mude nome e slug
*
* essas classes tem q ter um esquema de validação, (filtro, unicidade)
*
* $Collections->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;
}
}

View File

@ -1,19 +1,18 @@
#!/usr/bin/env bash
if [ $# -lt 3 ]; then
echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version] [skip-database-creation]"
if [ $# -lt 5 ]; then
echo "usage: $0 <db-name> <db-user> <db-pass> <test-dir> [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

View File

@ -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']);
}
}