diff --git a/application/controllers/api/frontend/v1/Bookmark.php b/application/controllers/api/frontend/v1/Bookmark.php index c43ad1c7a..ca18d0b7e 100644 --- a/application/controllers/api/frontend/v1/Bookmark.php +++ b/application/controllers/api/frontend/v1/Bookmark.php @@ -272,23 +272,5 @@ class Bookmark extends FHCAPI_Controller $this->terminateWithSuccess($update_result); } - - /** - * @SWG\Get( - * path="/test_true", - * security={{"basicAuth":{}}}, - * tags={"bookmarks"}, - * summary="Test endpoint", - * description="Simple test endpoint that returns 'expected response'.", - * @SWG\Response( - * response=200, - * description="Expected response" - * ) - * ) - */ - public function test_true() - { - echo "expected response"; - } } diff --git a/index.phpunit.php b/index.phpunit.php deleted file mode 100644 index d32f6f495..000000000 --- a/index.phpunit.php +++ /dev/null @@ -1,30 +0,0 @@ - - - - - ./system/IntegrationTests/api/ - - - - - - diff --git a/system/IntegrationTests/CIIntegrationTestCase.php b/system/IntegrationTests/CIIntegrationTestCase.php deleted file mode 100644 index ec4abcf3e..000000000 --- a/system/IntegrationTests/CIIntegrationTestCase.php +++ /dev/null @@ -1,55 +0,0 @@ -CI =& get_instance(); - - // ensure any old URI/router state is cleared - $this->CI->uri->uri_string = ''; - $this->CI->router->_set_routing([]); - } - - /** - * Simulate an HTTP request through CI’s front controller. - * - * @param string $method GET|POST|PUT|DELETE - * @param string $uri URI string, e.g. "bookmark/getBookmarks" - * @param array $params query‐params if GET, post‐data otherwise - * @return string raw response body - */ - protected function request(string $method, string $uri, array $params = []): string - { - // 1) fake the server vars - $_SERVER['REQUEST_METHOD'] = strtoupper($method); - $_SERVER['PATH_INFO'] = '/' . ltrim($uri, '/'); - if (strtoupper($method) === 'GET') { - $_GET = $params; - $_POST = []; - } else { - $_POST = $params; - $_GET = []; - } - - // 2) re-initialize routing/URI so CI picks up our fake PATH_INFO - $this->CI->router->_set_routing(); - $this->CI->uri->_set_uri_string($_SERVER['PATH_INFO']); - // pull class/method out of the path - $segments = explode('/', trim($_SERVER['PATH_INFO'], '/')); - $class = array_shift($segments) ?: 'welcome'; - $method = array_shift($segments) ?: 'index'; - $this->CI->router->set_class($class); - $this->CI->router->set_method($method); - - // 3) capture output - ob_start(); - require BASEPATH . 'core/CodeIgniter.php'; - return ob_get_clean(); - } -} diff --git a/system/IntegrationTests/api/BookmarkTest/BookmarkTest.php b/system/IntegrationTests/api/BookmarkTest/BookmarkTest.php deleted file mode 100644 index 07b592037..000000000 --- a/system/IntegrationTests/api/BookmarkTest/BookmarkTest.php +++ /dev/null @@ -1,149 +0,0 @@ -bookmarkModel = $this - ->getMockBuilder('Bookmark_model') - ->setMethods(['loadWhere','load','insert','update','delete']) - ->getMock(); - - // 2) inject it into CI - $this->CI->load->model('dashboard/Bookmark_model', 'BookmarkModel'); - $this->CI->BookmarkModel = $this->bookmarkModel; - - // 3) force a known user ID - $this->CI->uid = 42; - } - - public function test_test_true_endpoint() - { - $out = $this->request('GET', 'bookmark/test_true'); - $this->assertEquals('expected response', trim($out)); - } - - public function test_getBookmarks_returns_ordered_array() - { - $dummy = [ - (object)['bookmark_id'=>1,'url'=>'a','uid'=>42], - (object)['bookmark_id'=>2,'url'=>'b','uid'=>42], - ]; - // expect loadWhere() → our dummy - $this->bookmarkModel - ->expects($this->once()) - ->method('loadWhere') - ->with(['uid'=>42]) - ->willReturn($dummy); - - $out = $this->request('GET', 'bookmark/getBookmarks'); - $data = json_decode($out); - $this->assertCount(2, $data); - $this->assertEquals(1, $data[0]->bookmark_id); - } - - public function test_delete_own_bookmark_succeeds() - { - // load() → record owned by our uid - $this->bookmarkModel - ->expects($this->once()) - ->method('load') - ->with(5) - ->willReturn([(object)['bookmark_id'=>5,'uid'=>42]]); - - // delete() → true - $this->bookmarkModel - ->expects($this->once()) - ->method('delete') - ->with(5) - ->willReturn(true); - - $out = $this->request('DELETE', 'bookmark/delete/5'); - $this->assertJsonStringEqualsJsonString('true', $out); - } - - public function test_delete_not_owned_forbidden() - { - // load() → record owned by someone else - $this->bookmarkModel - ->method('load') - ->willReturn([(object)['bookmark_id'=>8,'uid'=>99]]); - - $out = $this->request('DELETE', 'bookmark/delete/8'); - // your controller does → $this->_outputAuthError(), typically 403 - $this->assertStringContainsString('403', $out); - } - - public function test_insert_validation_error() - { - // send invalid data - $out = $this->request('POST', 'bookmark/insert', [ - 'url' => 'not-a-url', - 'title' => '' - ]); - // expecting JSON validation errors - $json = json_decode($out, true); - $this->assertArrayHasKey('url', $json); - $this->assertArrayHasKey('title', $json); - } - - public function test_insert_success() - { - $input = [ - 'url' => 'https://example.org', - 'title' => 'Example', - 'tag' => 'phpunit', - ]; - // insert(...) → new ID 99 - $this->bookmarkModel - ->expects($this->once()) - ->method('insert') - ->with($this->callback(function($args) use($input) { - return $args['url'] === $input['url'] - && $args['title'] === $input['title'] - && $args['uid'] === 42; - })) - ->willReturn(99); - - $out = $this->request('POST', 'bookmark/insert', $input); - $this->assertJsonStringEqualsJsonString('99', $out); - } - - public function test_update_validation_error() - { - $out = $this->request('POST', 'bookmark/update/3', [ - 'url' => 'bad', - 'title' => '' - ]); - $json = json_decode($out, true); - $this->assertArrayHasKey('url', $json); - $this->assertArrayHasKey('title', $json); - } - - public function test_update_success() - { - $this->bookmarkModel - ->expects($this->once()) - ->method('update') - ->with(3, $this->callback(function($d){ - return filter_var($d['url'], FILTER_VALIDATE_URL) - && isset($d['updateamum']); - })) - ->willReturn(true); - - $out = $this->request('POST', 'bookmark/update/3', [ - 'url' => 'https://ci.org', - 'title' => 'CI3', - ]); - $this->assertJsonStringEqualsJsonString('true', $out); - } -} diff --git a/system/UnitTests/AssertionHelpers.php b/system/UnitTests/AssertionHelpers.php new file mode 100644 index 000000000..ec5211617 --- /dev/null +++ b/system/UnitTests/AssertionHelpers.php @@ -0,0 +1,73 @@ +❌ Assertion failed: $message
"; + echo "Expected:
" . var_export($expected, true) . "
"; + echo "Actual:
" . var_export($actual, true) . "
"; + return false; + } else { + echo "✅ Passed: $message
"; + 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 "❌ Assertion failed: $message
"; + echo "Value is null
"; + return false; + } else { + echo "✅ Passed: $message
"; + 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"); +} diff --git a/system/UnitTests/CI_TestCase.php b/system/UnitTests/CI_TestCase.php deleted file mode 100644 index bc9b9d62f..000000000 --- a/system/UnitTests/CI_TestCase.php +++ /dev/null @@ -1,17 +0,0 @@ -_ci =& get_instance(); - } - - public function __get($name) - { - return $this->_ci->$name; - } -} diff --git a/system/UnitTests/api/BookmarkTest/BookmarkIntegrationTest.php b/system/UnitTests/api/BookmarkTest/BookmarkIntegrationTest.php deleted file mode 100644 index c8ea39c1e..000000000 --- a/system/UnitTests/api/BookmarkTest/BookmarkIntegrationTest.php +++ /dev/null @@ -1,80 +0,0 @@ -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 fine‐grained 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()); - } -} diff --git a/system/UnitTests/api/BookmarkTest/BookmarkTest.php b/system/UnitTests/api/BookmarkTest/BookmarkTest.php index 89d507f08..2c6ca9389 100644 --- a/system/UnitTests/api/BookmarkTest/BookmarkTest.php +++ b/system/UnitTests/api/BookmarkTest/BookmarkTest.php @@ -1,28 +1,189 @@ bookmark = new Bookmark(); // or $this->CI->bookmark -// } -// -// /** @test */ -// public function test_true() -// { -// echo "expected response"; -// -// } -// -// -//} \ No newline at end of file + +echo "Test Suite Bookmark start \r\n"; +echo "
"; + +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 "
"; + +// 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 "

Test '".$method."' start \r\n"; + echo "
"; + 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
"; + } else { + echo "Test '".$method."' finished FAIL
"; + printResponse($resultPost); + } +} + +function testInsertBookmark($url, $method, $user, $pw) { + echo "

Test '".$method."' start \r\n"; + echo "
"; + 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
"; + } else { + echo "Test '".$method."' finished FAIL
"; + printResponse($resultPost); + } + + return $resultPost->body->data; +} + +function testDeleteBookmark($url, $method, $user, $pw, $id) { + echo "

Test '".$method."' start \r\n"; + echo "
"; + + 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
"; + } else { + echo "Test '".$method."' finished FAIL
"; + printResponse($resultPost); + } +} + +function testUpdateBookmark($url, $method, $user, $pw, $id) { + echo "

Test '".$method."' start \r\n"; + echo "
"; + + 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
"; + } else { + echo "Test '".$method."' finished FAIL
"; + printResponse($resultPost); + } + + return $resultPost->body->data; +} + +function printResponse($resultPost) { + echo "
"; + echo "Response Body:\n"; + print_r($resultPost->body); + echo "
"; + echo "Raw Response:\n"; + print_r($resultPost->raw_body); + echo "
"; + echo "Status Code:\n"; + print_r($resultPost->code); + echo "
"; + echo "Headers:\n"; + print_r($resultPost->headers); + echo "
"; +} + +function allTrue($arr) { + return count(array_filter($arr, function($v) { + return $v === true; + })) === count($arr); +} + + + + diff --git a/testbootstrap.php b/testbootstrap.php deleted file mode 100644 index 87d495210..000000000 --- a/testbootstrap.php +++ /dev/null @@ -1,41 +0,0 @@ -