proof of concept Blackbox TestSuite using httpful to call Bookmark API Controller and test for expected responses; cleanup old phpunit testing attempt relics; WIP enhancing the script/helper functions further;

This commit is contained in:
Johann Hoffmann
2025-07-14 15:44:27 +02:00
parent f888dcc72d
commit ffaf360ea0
10 changed files with 261 additions and 428 deletions
+73
View File
@@ -0,0 +1,73 @@
<?php
function assertEqual($expected, $actual, $message = '') {
if ($expected !== $actual) {
echo "<b style='color:red;'>❌ Assertion failed:</b> $message<br>";
echo "Expected: <pre>" . var_export($expected, true) . "</pre>";
echo "Actual: <pre>" . var_export($actual, true) . "</pre>";
return false;
} else {
echo "<b style='color:green;'>✅ Passed:</b> $message<br>";
return true;
}
}
function assertTrue($condition, $message = '') {
return assertEqual(true, $condition, $message ?: 'Expected condition to be true');
}
function assertFalse($condition, $message = '') {
return assertEqual(false, $condition, $message ?: 'Expected condition to be false');
}
function assertNull($value, $message = '') {
return assertEqual(null, $value, $message ?: 'Expected value to be null');
}
function assertNotNull($value, $message = '') {
if ($value === null) {
echo "<b style='color:red;'>❌ Assertion failed:</b> $message<br>";
echo "Value is null<br>";
return false;
} else {
echo "<b style='color:green;'>✅ Passed:</b> $message<br>";
return true;
}
}
function assertIsArray($value, $message = '') {
return assertEqual(true, is_array($value), $message ?: 'Expected value to be an array');
}
function assertIsObject($value, $message = '') {
return assertEqual(true, is_object($value), $message ?: 'Expected value to be an object');
}
function assertIsString($value, $message = '') {
return assertEqual(true, is_string($value), $message ?: 'Expected value to be a string');
}
function assertIsInt($value, $message = '') {
return assertEqual(true, is_int($value), $message ?: 'Expected value to be an integer');
}
function assertIsFloat($value, $message = '') {
return assertEqual(true, is_float($value), $message ?: 'Expected value to be a float');
}
function assertIsBool($value, $message = '') {
return assertEqual(true, is_bool($value), $message ?: 'Expected value to be a boolean');
}
function assertArrayHasKey($key, $array, $message = '') {
return assertEqual(true, array_key_exists($key, $array), $message ?: "Expected key '$key' in array");
}
function assertObjectHasProperty($property, $object, $message = '') {
return assertEqual(true, property_exists($object, $property), $message ?: "Expected property '$property' in object");
}
function assertCount($expectedCount, $arrayOrCountable, $message = '') {
return assertEqual($expectedCount, count($arrayOrCountable), $message ?: "Expected count of $expectedCount");
}
-17
View File
@@ -1,17 +0,0 @@
<?php
use PHPUnit\Framework\TestCase;
class CI_TestCase extends TestCase
{
public $_ci;
public function setUp()
{
$this->_ci =& get_instance();
}
public function __get($name)
{
return $this->_ci->$name;
}
}
@@ -1,80 +0,0 @@
<?php
// tests/Integration/ApiControllerTest.php
use PHPUnit\Framework\TestCase;
class BookmarkIntegrationTest extends TestCase
{
/** @var CI_Controller */
protected $CI;
public function setUp()
{
// Grab the global CI instance
$this->CI =& get_instance();
// Make sure we're in a clean state:
// - no lingering URI segments
// - fresh router rules
$this->CI->uri->uri_string = '';
$this->CI->router->_set_routing([]);
}
/**
* Simulate a GET to /api/users and assert JSON list
*/
public function testGetUsersReturnsJsonArray()
{
// 1) Fake server variables
$_SERVER['REQUEST_METHOD'] = 'GET';
// you can use PATH_INFO or REQUEST_URI depending on your config
$_SERVER['PATH_INFO'] = '/api/users';
$_GET = []; $_POST = [];
// 2) Re-run routing so CI picks up our fake path
$this->CI->router->_set_routing();
$this->CI->uri->_set_uri_string('/api/users');
$this->CI->router->set_class('api');
$this->CI->router->set_method('users');
// 3) Capture the output
ob_start();
// This is the entry point:
// core/CodeIgniter.php will look at $RTR->class/method
// instantiate your Api controller, call ->users()
require BASEPATH . 'core/CodeIgniter.php';
$output = ob_get_clean();
// 4) Assert JSON shape, status header, etc.
$this->assertNotEmpty($output, 'No output at all');
$decoded = json_decode($output, true);
$this->assertIsArray($decoded, 'Expected JSON array');
// more finegrained assertions…
}
/**
* Simulate a POST to /api/users
*/
public function testCreateUser()
{
$_SERVER['REQUEST_METHOD'] = 'POST';
$_SERVER['PATH_INFO'] = '/api/users';
$_POST = [
'name' => 'Alice',
'email' => 'alice@example.com',
];
$_GET = [];
$this->CI->router->_set_routing();
$this->CI->uri->_set_uri_string('/api/users');
$this->CI->router->set_class('api');
$this->CI->router->set_method('users');
ob_start();
require BASEPATH . 'core/CodeIgniter.php';
$out = ob_get_clean();
$this->assertStringContainsString('"id":', $out);
$this->assertMatchesRegularExpression('/201 Created/', xdebug_get_headers());
}
}
@@ -1,28 +1,189 @@
<?php
//
//echo "BookmarkTest loaded\n";
//require_once __DIR__ . '/../../CI_TestCase.php';
//
//class BookmarkTest extends CI_TestCase
//{
//
// public function setUp()
// {
// parent::setUp();
//
//// require_once APPPATH . 'core/FHC_Controller.php';
//// require_once APPPATH . 'core/Auth_Controller.php';
//// require_once APPPATH . 'core/FHCAPI_Controller.php';
// require_once APPPATH . 'controllers/api/frontend/v1/Bookmark.php';
// $this->bookmark = new Bookmark(); // or $this->CI->bookmark
// }
//
// /** @test */
// public function test_true()
// {
// echo "expected response";
//
// }
//
//
//}
echo "Test Suite Bookmark start \r\n";
echo "<br>";
require_once(dirname(__FILE__).'/../../../../config/cis.config.inc.php');
require_once(dirname(__FILE__).'/../../../../vendor/nategood/httpful/bootstrap.php');
require_once(dirname(__FILE__).'/../../AssertionHelpers.php');
echo "Requirements loaded \r\n";
echo "<br>";
// TODO: parameterize for different user setups
$TEST_USER = 'if23b236';
$TEST_PW = 'FHCompleteDemo42!';
// "Unit Test" Script to Test API Controller frontend/v1/Bookmark.php by calling methods with curated inputs and checking
// for the expected output
$ROOT = APP_ROOT; // calls itself -> TODO: switch for other machines
//$ROOT = 'https://ci.dev.technikum-wien.at/';
//$ROOT = 'https://cis40.dev.technikum-wien.at/';
$URL = $ROOT.'cis.php/api/frontend/v1/Bookmark/';
testGetBookmarks($URL, 'getBookmarks', $TEST_USER, $TEST_PW);
$id = testInsertBookmark($URL, 'insert', $TEST_USER, $TEST_PW);
$id = testUpdateBookmark($URL, 'update', $TEST_USER, $TEST_PW, $id);
testDeleteBookmark($URL, 'delete', $TEST_USER, $TEST_PW, $id);
function testGetBookmarks($url, $method, $user, $pw) {
echo "<br><br>Test '".$method."' start \r\n";
echo "<br>";
try {
$resultPost = \Httpful\Request::get($url.$method)
->expectsJson()
->authenticateWith($user, $pw)
->send();
} catch(\Httpful\Exception\ConnectionErrorException $cee) // Httpful exception
{
echo $cee;
}
catch (Exception $e) // any other exception
{
echo $e;
}
$assertions = [];
$assertions[] = assertIsArray($resultPost->body->data);
$assertions[] = assertIsString($resultPost->body->meta->status);
$assertions[] = assertEqual($resultPost->body->meta->status, "success", "Response Status Success");
if(allTrue($assertions)) {
echo "Test '".$method."' finished SUCCESS<br>";
} else {
echo "Test '".$method."' finished FAIL<br>";
printResponse($resultPost);
}
}
function testInsertBookmark($url, $method, $user, $pw) {
echo "<br><br>Test '".$method."' start \r\n";
echo "<br>";
try {
$bodyTitle = 'orf';
$bodyUrl = 'https://orf.at';
$resultPost = \Httpful\Request::post($url.$method)
->expectsJson()
->authenticateWith($user, $pw)
->sendsJson()
->body('{"title": "'.$bodyTitle.'", "url": "'.$bodyUrl.'"}')
->send();
} catch(\Httpful\Exception\ConnectionErrorException $cee) // Httpful exception
{
echo $cee;
}
catch (Exception $e) // any other exception
{
echo $e;
}
$assertions = [];
$assertions[] = assertIsInt($resultPost->body->data);
$assertions[] = assertIsString($resultPost->body->meta->status);
$assertions[] = assertEqual("success",$resultPost->body->meta->status, "Response Status Success");
if(allTrue($assertions)) {
echo "Test '".$method."' finished SUCCESS<br>";
} else {
echo "Test '".$method."' finished FAIL<br>";
printResponse($resultPost);
}
return $resultPost->body->data;
}
function testDeleteBookmark($url, $method, $user, $pw, $id) {
echo "<br><br>Test '".$method."' start \r\n";
echo "<br>";
try {
$resultPost = \Httpful\Request::post($url.$method.'/'.$id)
->expectsJson()
->authenticateWith($user, $pw)
->sendsJson()
->send();
} catch(\Httpful\Exception\ConnectionErrorException $cee) // Httpful exception
{
echo $cee;
}
catch (Exception $e) // any other exception
{
echo $e;
}
$assertions = [];
$assertions[] = assertIsString($resultPost->body->data);
$assertions[] = assertIsString($resultPost->body->meta->status);
$assertions[] = assertEqual("success",$resultPost->body->meta->status, "Response Status Success");
if(allTrue($assertions)) {
echo "Test '".$method."' finished SUCCESS<br>";
} else {
echo "Test '".$method."' finished FAIL<br>";
printResponse($resultPost);
}
}
function testUpdateBookmark($url, $method, $user, $pw, $id) {
echo "<br><br>Test '".$method."' start \r\n";
echo "<br>";
try {
$bodyTitle = 'orf title updated';
$bodyUrl = 'https://orf.at';
$resultPost = \Httpful\Request::post($url.$method.'/'.$id)
->expectsJson()
->authenticateWith($user, $pw)
->body('{"title": "'.$bodyTitle.'", "url": "'.$bodyUrl.'"}')
->sendsJson()
->send();
} catch(\Httpful\Exception\ConnectionErrorException $cee) // Httpful exception
{
echo $cee;
}
catch (Exception $e) // any other exception
{
echo $e;
}
$assertions = [];
$assertions[] = assertIsString($resultPost->body->data);
$assertions[] = assertIsString($resultPost->body->meta->status);
$assertions[] = assertEqual("success",$resultPost->body->meta->status, "Response Status Success");
if(allTrue($assertions)) {
echo "Test '".$method."' finished SUCCESS<br>";
} else {
echo "Test '".$method."' finished FAIL<br>";
printResponse($resultPost);
}
return $resultPost->body->data;
}
function printResponse($resultPost) {
echo "<br>";
echo "Response Body:\n";
print_r($resultPost->body);
echo "<br>";
echo "Raw Response:\n";
print_r($resultPost->raw_body);
echo "<br>";
echo "Status Code:\n";
print_r($resultPost->code);
echo "<br>";
echo "Headers:\n";
print_r($resultPost->headers);
echo "<br>";
}
function allTrue($arr) {
return count(array_filter($arr, function($v) {
return $v === true;
})) === count($arr);
}