Merge pull request #5022 from Rudloff/feature/test_api

Add API tests
This commit is contained in:
Hypolite Petovan 2018-05-16 08:25:11 -04:00 committed by GitHub
commit ce75177d4e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 5383 additions and 21 deletions

View file

@ -7,4 +7,14 @@ php:
- 7.1 - 7.1
- 7.2 - 7.2
install: composer install services:
- mysql
env:
- USER=travis DB=test
install:
- composer install
before_script:
- mysql -e 'CREATE DATABASE IF NOT EXISTS test;'
# In order to avoid bin/worker.php warnings
- touch .htconfig.php

View file

@ -47,7 +47,8 @@
], ],
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Friendica\\": "src/" "Friendica\\": "src/",
"Friendica\\Test\\": "tests/"
}, },
"psr-0": { "psr-0": {
"": "library/" "": "library/"
@ -68,5 +69,13 @@
"exclude": [ "exclude": [
"log", "cache", "/photo", "/proxy" "log", "cache", "/photo", "/proxy"
] ]
},
"require-dev": {
"phpunit/dbunit": "^2.0",
"phpdocumentor/reflection-docblock": "^3.0.2",
"phpunit/php-token-stream": "^1.4.2"
},
"scripts": {
"test": "phpunit"
} }
} }

1379
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -50,6 +50,7 @@ Friendica Documentation and Resources
* [Translate Friendica](help/translations) * [Translate Friendica](help/translations)
* [Use Composer](help/Composer) * [Use Composer](help/Composer)
* [Move classes to `src`](help/Developer-How-To-Move-Classes-to-src) * [Move classes to `src`](help/Developer-How-To-Move-Classes-to-src)
* [Run tests](help/Tests)
* Reference * Reference
* [Twitter/GNU Social API Functions](help/api) * [Twitter/GNU Social API Functions](help/api)
* [Code (Doxygen generated - sets cookies)](doc/html/) * [Code (Doxygen generated - sets cookies)](doc/html/)
@ -71,4 +72,3 @@ Friendica Documentation and Resources
* [Site/Version Info](friendica) * [Site/Version Info](friendica)
* [Friendica Credits](credits) * [Friendica Credits](credits)

18
doc/Tests.md Normal file
View file

@ -0,0 +1,18 @@
# Themes
* [Home](help)
You can run unit tests with [PHPUnit](https://phpunit.de/):
```bash
phpunit
```
Some tests require access to a MySQL database.
You can specify the database credentials in environment variables:
```bash
USER=database_user PASS=database_password DB=database_name phpunit
```
**Warning**: This will empty all the tables! Never use this on a production database.

View file

@ -55,6 +55,7 @@ Friendica - Dokumentation und Ressourcen
* [Code-Referenz (mit doxygen generiert - setzt Cookies)](doc/html/) * [Code-Referenz (mit doxygen generiert - setzt Cookies)](doc/html/)
* [Twitter/GNU Social API Functions](help/api) (EN) * [Twitter/GNU Social API Functions](help/api) (EN)
* [Translation of Friendica](help/translations) (EN) * [Translation of Friendica](help/translations) (EN)
* [Run tests](help/Tests) (EN)
**Externe Ressourcen** **Externe Ressourcen**
@ -71,4 +72,3 @@ Friendica - Dokumentation und Ressourcen
* [Seite/Friendica-Version](friendica) * [Seite/Friendica-Version](friendica)
* [Mitwirkenden bei Friendica](credits) * [Mitwirkenden bei Friendica](credits)

View file

@ -54,7 +54,7 @@ define('API_METHOD_POST', 'POST,PUT');
define('API_METHOD_DELETE', 'POST,DELETE'); define('API_METHOD_DELETE', 'POST,DELETE');
$API = []; $API = [];
$called_api = null; $called_api = [];
/** /**
* It is not sufficient to use local_user() to check whether someone is allowed to use the API, * It is not sufficient to use local_user() to check whether someone is allowed to use the API,
@ -2200,7 +2200,7 @@ function api_statuses_repeat($type)
} }
// this should output the last post (the one we just posted). // this should output the last post (the one we just posted).
$called_api = null; $called_api = [];
return api_status_show($type); return api_status_show($type);
} }
@ -2716,7 +2716,7 @@ function api_convert_item($item)
* *
* @param string $body * @param string $body
* *
* @return array|false * @return array
*/ */
function api_get_attachments(&$body) function api_get_attachments(&$body)
{ {
@ -2727,7 +2727,7 @@ function api_get_attachments(&$body)
$ret = preg_match_all("/\[img\]([$URLSearchString]*)\[\/img\]/ism", $text, $images); $ret = preg_match_all("/\[img\]([$URLSearchString]*)\[\/img\]/ism", $text, $images);
if (!$ret) { if (!$ret) {
return false; return [];
} }
$attachments = []; $attachments = [];

View file

@ -102,6 +102,15 @@ class dba {
return self::$connected; return self::$connected;
} }
/**
* Return the database object.
* @return PDO|mysqli
*/
public static function get_db()
{
return self::$db;
}
/** /**
* @brief Returns the MySQL server version string * @brief Returns the MySQL server version string
* *

View file

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<phpunit bootstrap="boot.php"> <phpunit bootstrap="tests/bootstrap.php">
<testsuites> <testsuites>
<testsuite> <testsuite>
<directory>tests/</directory> <directory>tests/</directory>

3669
tests/ApiTest.php Normal file

File diff suppressed because it is too large Load diff

View file

@ -7,14 +7,12 @@ namespace Friendica\Test;
use Friendica\App; use Friendica\App;
use Friendica\BaseObject; use Friendica\BaseObject;
// backward compatibility use PHPUnit\Framework\TestCase;
if (!class_exists('\PHPUnit\Framework\TestCase')) {
class_alias('\PHPUnit_Framework_TestCase', '\PHPUnit\Framework\TestCase');
}
/** /**
* Tests for the BaseObject class. * Tests for the BaseObject class.
*/ */
class BaseObjectTest extends \PHPUnit\Framework\TestCase class BaseObjectTest extends TestCase
{ {
/** /**

63
tests/DatabaseTest.php Normal file
View file

@ -0,0 +1,63 @@
<?php
/**
* DatabaseTest class.
*/
namespace Friendica\Test;
use dba;
use Friendica\Database\DBStructure;
use PHPUnit_Extensions_Database_DB_IDatabaseConnection;
use PHPUnit\DbUnit\DataSet\YamlDataSet;
use PHPUnit\DbUnit\TestCaseTrait;
use PHPUnit\Framework\TestCase;
/**
* Abstract class used by tests that need a database.
*/
abstract class DatabaseTest extends TestCase
{
use TestCaseTrait;
/**
* Get database connection.
*
* This function is executed before each test in order to get a database connection that can be used by tests.
* If no prior connection is available, it tries to create one using the USER, PASS and DB environment variables.
*
* If it could not connect to the database, the test is skipped.
*
* @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
* @see https://phpunit.de/manual/5.7/en/database.html
*/
protected function getConnection()
{
if (!dba::$connected) {
dba::connect('localhost', getenv('USER'), getenv('PASS'), getenv('DB'));
if (dba::$connected) {
$app = get_app();
// We need to do this in order to disable logging
$app->module = 'install';
// Create database structure
DBStructure::update(false, true, true);
} else {
$this->markTestSkipped('Could not connect to the database.');
}
}
return $this->createDefaultDBConnection(dba::get_db(), getenv('DB'));
}
/**
* Get dataset to populate the database with.
* @return YamlDataSet
* @see https://phpunit.de/manual/5.7/en/database.html
*/
protected function getDataSet()
{
return new YamlDataSet(__DIR__ . '/datasets/api.yml');
}
}

View file

@ -5,15 +5,12 @@
namespace Friendica\Test; namespace Friendica\Test;
// backward compatibility use PHPUnit\Framework\TestCase;
if (!class_exists('\PHPUnit\Framework\TestCase')) {
class_alias('\PHPUnit_Framework_TestCase', '\PHPUnit\Framework\TestCase');
}
/** /**
* Tests for text functions. * Tests for text functions.
*/ */
class TextTest extends \PHPUnit\Framework\TestCase class TextTest extends TestCase
{ {
/** /**

22
tests/bootstrap.php Normal file
View file

@ -0,0 +1,22 @@
<?php
/**
* This file is loaded by PHPUnit before any test.
*/
use PHPUnit\DbUnit\DataSet\YamlDataSet;
use PHPUnit\DbUnit\TestCaseTrait;
use PHPUnit\Framework\TestCase;
require_once __DIR__.'/../boot.php';
require_once __DIR__.'/../include/api.php';
// Backward compatibility
if (!class_exists(TestCase::class)) {
class_alias(PHPUnit_Framework_TestCase::class, TestCase::class);
}
if (!trait_exists(TestCaseTrait::class)) {
class_alias(PHPUnit_Extensions_Database_TestCase_Trait::class, TestCaseTrait::class);
}
if (!class_exists(YamlDataSet::class)) {
class_alias(PHPUnit_Extensions_Database_DataSet_YamlDataSet::class, YamlDataSet::class);
}

192
tests/datasets/api.yml Normal file
View file

@ -0,0 +1,192 @@
---
# Empty these tables
cache:
config:
conversation:
pconfig:
photo:
workerqueue:
mail:
# Populate tables with test data
user:
-
uid: 42
username: Test user
nickname: selfcontact
verified: true
password: $2y$10$DLRNTRmJgKe1cSrFJ5Jb0edCqvXlA9sh/RHdSnfxjbR.04yZRm4Qm
theme: frio
contact:
-
id: 42
uid: 42
name: Self contact
nick: selfcontact
self: true
nurl: http://localhost/profile/selfcontact
url: http://localhost/profile/selfcontact
about: User used in tests
pending: false
blocked: false
rel: 1
network: dfrn
-
id: 43
uid: 0
# Having the same name and nick allows us to test
# the fallback to api_get_nick() in api_get_user()
name: othercontact
nick: othercontact
self: false
nurl: http://localhost/profile/othercontact
url: http://localhost/profile/othercontact
pending: false
blocked: false
rel: 0
network: dfrn
-
id: 44
uid: 42
name: Friend contact
nick: friendcontact
self: false
nurl: http://localhost/profile/friendcontact
url: http://localhost/profile/friendcontact
pending: false
blocked: false
rel: 2
network: dfrn
item:
-
id: 1
visible: true
contact-id: 42
author-id: 42
owner-id: 42
uid: 42
verb: http://activitystrea.ms/schema/1.0/post
unseen: true
body: Parent status
parent: 1
author-link: http://localhost/profile/selfcontact
wall: true
starred: true
allow_cid: ''
allow_gid: ''
deny_cid: ''
deny_gid: ''
-
id: 2
visible: true
contact-id: 42
author-id: 42
owner-id: 42
uid: 42
verb: http://activitystrea.ms/schema/1.0/post
unseen: false
body: Reply
parent: 1
author-link: http://localhost/profile/selfcontact
wall: true
starred: false
-
id: 3
visible: true
contact-id: 43
author-id: 43
owner-id: 42
uid: 42
verb: http://activitystrea.ms/schema/1.0/post
unseen: false
body: Other user status
parent: 3
author-link: http://localhost/profile/othercontact
wall: true
starred: false
-
id: 4
visible: true
contact-id: 43
author-id: 43
owner-id: 42
uid: 42
verb: http://activitystrea.ms/schema/1.0/post
unseen: false
body: Other user reply
parent: 1
author-link: http://localhost/profile/othercontact
wall: true
starred: false
-
id: 5
visible: true
contact-id: 42
author-id: 42
owner-id: 42
uid: 42
verb: http://activitystrea.ms/schema/1.0/post
unseen: false
body: '[share]Shared status[/share]'
parent: 1
author-link: http://localhost/profile/othercontact
wall: true
starred: false
allow_cid: ''
allow_gid: ''
deny_cid: ''
deny_gid: ''
-
id: 6
visible: true
contact-id: 44
author-id: 44
owner-id: 42
uid: 42
verb: http://activitystrea.ms/schema/1.0/post
unseen: false
body: Friend user status
parent: 6
author-link: http://localhost/profile/othercontact
wall: true
starred: false
thread:
-
iid: 1
visible: true
contact-id: 42
uid: 42
wall: true
-
iid: 3
visible: true
contact-id: 43
uid: 0
wall: true
-
iid: 6
visible: true
contact-id: 44
uid: 0
wall: true
group:
-
id: 1
uid: 42
visible: true
name: Visible list
-
id: 2
uid: 42
visible: false
name: Private list
search:
-
id: 1
term: Saved search
uid: 42