diff --git a/tests/HLAPITestCase.php b/phpunit/HLAPITestCase.php similarity index 69% rename from tests/HLAPITestCase.php rename to phpunit/HLAPITestCase.php index bc162529a45..76d34e543b6 100644 --- a/tests/HLAPITestCase.php +++ b/phpunit/HLAPITestCase.php @@ -49,7 +49,6 @@ class HLAPITestCase extends \DbTestCase { private $bearer_token = null; - private $fake_score = null; public function afterTestMethod($method) { @@ -63,24 +62,6 @@ public function resetSession() parent::resetSession(); } - public function getScore() - { - // if this method wasn't called from the \atoum\atoum\asserter\exception class, we can return the real score - // We only need to intercept the score when it's called from the exception class so we can modify the data - $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); - if (count($trace) < 2 || $trace[1]['class'] !== 'atoum\atoum\asserter\exception') { - return parent::getScore(); - } - if ($this->fake_score === null) { - $real_score = parent::getScore(); - if ($real_score === null) { - return null; - } - $this->fake_score = new HLAPITestScore($real_score); - } - return $this->fake_score; - } - protected function loginWeb(string $user_name = TU_USER, string $user_pass = TU_PASS, bool $noauto = true, bool $expected = true): \Auth { return parent::login($user_name, $user_pass, $noauto, $expected); @@ -103,9 +84,10 @@ public function login(string $user_name = TU_USER, string $user_pass = TU_PASS, $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasKeys(['token_type', 'expires_in', 'access_token', 'refresh_token']); - $this->string($content['token_type'])->isEqualTo('Bearer'); - $this->string($content['access_token'])->isNotEmpty(); + $this->assertEquals('Bearer', $content['token_type']); + $this->assertNotEmpty($content['expires_in']); + $this->assertNotEmpty($content['access_token']); + $this->assertNotEmpty($content['refresh_token']); $this->bearer_token = $content['access_token']; }); }); @@ -123,19 +105,19 @@ protected function checkSimpleContentExpect(array $content, array $expected): vo $operator = $expected['count'][0]; switch ($operator) { case '>': - $this->integer(count($content))->isGreaterThan($expected['count'][1]); + $this->assertGreaterThan($expected['count'][1], count($content)); break; case '>=': - $this->integer(count($content))->isGreaterThanOrEqualTo($expected['count'][1]); + $this->assertGreaterThanOrEqual($expected['count'][1], count($content)); break; case '<': - $this->integer(count($content))->isLessThan($expected['count'][1]); + $this->assertLessThan($expected['count'][1], count($content)); break; case '<=': - $this->integer(count($content))->isLessThanOrEqualTo($expected['count'][1]); + $this->assertLessThanOrEqual($expected['count'][1], count($content)); break; case '=': - $this->integer(count($content))->isEqualTo($expected['count'][1]); + $this->assertEquals($expected['count'][1], count($content)); break; } } @@ -146,10 +128,9 @@ protected function checkSimpleContentExpect(array $content, array $expected): vo $parts = explode('.', $field); $current = $content; foreach ($parts as $part) { - $this->array($current)->hasKey($part); $current = $current[$part]; } - $this->variable($current)->isEqualTo($value); + $this->assertEquals($value, $current); } } } @@ -198,17 +179,6 @@ public function getRouter(): Router return $this->router; } - /** - * @return RoutePath[] - */ - private function getRoutes(): array - { - if (count(self::$routes_cache) === 0) { - self::$routes_cache = $this->router->getAllRoutes(); - } - return self::$routes_cache; - } - /** * @param string $endpoint * @return RoutePath[] @@ -226,26 +196,17 @@ private function getRoutesForEndpoint(string $endpoint): array return $all_routes; } - private function getRoutePathDoc(RoutePath $route_path, string $method, bool $required = true): Doc\Route - { - $doc = $route_path->getRouteDoc($method); - if ($required) { - $this->test->variable($doc)->isNotNull('No documentation found for route ' . $route_path->getRoutePath() . ' with method ' . $method); - } - return $doc; - } - private function getRoutePathBodySchema(RoutePath $route_path, string $method, array $attributes = []): array|null { $doc = $route_path->getRouteDoc($method); - $this->test->variable($doc)->isNotNull('No documentation found for route ' . $route_path->getRoutePath() . ' with method ' . $method); + $this->test->assertNotNull($doc, 'No documentation found for route ' . $route_path->getRoutePath() . ' with method ' . $method); $params = $doc->getParameters(); $body_params = array_filter($params, static fn ($param) => $param->getName() === '_' && $param->getLocation() === 'body'); if (empty($body_params)) { return null; } - $this->test->array($body_params)->hasSize(1, 'Multiple body parameters found for route ' . $route_path->getRoutePath() . ' with method ' . $method); + $this->test->assertCount(1, $body_params, 'Multiple body parameters found for route ' . $route_path->getRoutePath() . ' with method ' . $method); $body_param = array_values($body_params)[0]; $schema = $body_param->getSchema(); if ($schema instanceof Doc\SchemaReference) { @@ -264,7 +225,7 @@ private function getRoutePathBodySchema(RoutePath $route_path, string $method, a private function getRoutePathResponseSchema(RoutePath $route_path, string $method, $status = 200, array $attributes = []): array|null { $doc = $route_path->getRouteDoc($method); - $this->test->variable($doc)->isNotNull('No documentation found for route ' . $route_path->getRoutePath() . ' with method ' . $method); + $this->test->assertNotNull($doc, 'No documentation found for route ' . $route_path->getRoutePath() . ' with method ' . $method); $responses = $doc->getResponses(); $response = array_filter($responses, static fn ($response) => $response->getStatusCode() === $status)[0] ?? null; @@ -281,7 +242,7 @@ private function getRoutePathResponseSchema(RoutePath $route_path, string $metho private function routePathHasParameter(RoutePath $route_path, string $parameter, string $location): bool { $doc = $route_path->getRouteDoc('GET'); - $this->test->variable($doc)->isNotNull('No documentation found for route ' . $route_path->getRoutePath() . ' with method GET'); + $this->test->assertNotNull($doc, 'No documentation found for route ' . $route_path->getRoutePath() . ' with method GET'); $params = $doc->getParameters(); $matches = array_filter($params, static fn ($param) => $param->getName() === $parameter && $param->getLocation() === $location); @@ -308,7 +269,7 @@ public function hasMatch(Request $request) ) { $is_default_route = true; } - return $this->test->boolean($match !== null && !$is_default_route); + return $match !== null && !$is_default_route; } /** @@ -341,7 +302,7 @@ public function autoTestCRUD(string $endpoint, array $create_params = [], array } $required_methods = ['POST', 'GET', 'PATCH', 'DELETE']; $missing_methods = array_diff($required_methods, $all_methods); - $this->test->array($missing_methods)->isEmpty('The endpoint "' . $endpoint . '" does not support the following CRUD methods: ' . implode(', ', $missing_methods)); + $this->test->assertEmpty($missing_methods, 'The endpoint "' . $endpoint . '" does not support the following CRUD methods: ' . implode(', ', $missing_methods)); $schema = null; foreach ($routes as $route) { @@ -351,8 +312,8 @@ public function autoTestCRUD(string $endpoint, array $create_params = [], array break; } } - $this->test->variable($schema)->isNotNull('The POST route for endpoint "' . $endpoint . '" does not have a body schema'); - $this->test->string($schema['type'])->isEqualTo('object', 'The POST route for endpoint "' . $endpoint . '" body schema is not for an object'); + $this->test->assertNotNull($schema, 'The POST route for endpoint "' . $endpoint . '" does not have a body schema'); + $this->test->assertEquals('object', $schema['type'], 'The POST route for endpoint "' . $endpoint . '" body schema is not for an object'); $schema_json = json_encode($schema); $flattened_props = Doc\Schema::flattenProperties($schema['properties'] ?? []); @@ -360,19 +321,15 @@ public function autoTestCRUD(string $endpoint, array $create_params = [], array $attributes = $route->getAttributesFromPath($endpoint); if (in_array('GET', $route->getRouteMethods(), true) && str_ends_with($route->getRoutePath(), '/{id}')) { $get_schema = $this->getRoutePathResponseSchema(route_path: $route, method: 'GET', attributes: $attributes); - $this->test - ->variable($get_schema)->isNotNull('The GET route for endpoint "' . $endpoint . '" does not have a response schema'); - $this->test - ->string(json_encode($get_schema))->isEqualTo($schema_json, 'The POST route for endpoint "' . $endpoint . '" body schema does not match the GET route response schema'); + $this->test->assertNotNull($get_schema, 'The GET route for endpoint "' . $endpoint . '" does not have a response schema'); + $this->test->assertEquals($schema_json, json_encode($get_schema), 'The POST route for endpoint "' . $endpoint . '" body schema does not match the GET route response schema'); } else if (in_array('PATCH', $route->getRouteMethods(), true)) { $patch_schema = $this->getRoutePathBodySchema(route_path: $route, method: 'PATCH', attributes: $attributes); - $this->test - ->variable($patch_schema)->isNotNull('The PATCH route for endpoint "' . $endpoint . '" does not have a body schema'); - $this->test - ->string(json_encode($patch_schema))->isEqualTo($schema_json, 'The input body for the POST route path and the body for the PATCH route path of endpoint "' . $endpoint . '" do not match'); + $this->test->assertNotNull($patch_schema, 'The PATCH route for endpoint "' . $endpoint . '" does not have a body schema'); + $this->test->assertEquals($schema_json, json_encode($patch_schema), 'The input body for the POST route path and the body for the PATCH route path of endpoint "' . $endpoint . '" do not match'); } else if (in_array('DELETE', $route->getRouteMethods(), true)) { $delete_schema = $this->getRoutePathBodySchema(route_path: $route, method: 'DELETE', attributes: $attributes); - $this->test->variable($delete_schema)->isNull('The DELETE route for endpoint "' . $endpoint . '" has a body schema'); + $this->test->assertNull($delete_schema, 'The DELETE route for endpoint "' . $endpoint . '" has a body schema'); } } @@ -408,18 +365,13 @@ public function autoTestCRUD(string $endpoint, array $create_params = [], array $call->response ->isOK() ->jsonContent(function ($content) use ($endpoint) { - $this->test->array($content) - ->hasKey('id', 'The response for the POST route path of endpoint "' . $endpoint . '" does not have an "id" field'); - $this->test->integer($content['id']) - ->isGreaterThan(0, 'The response for the POST route path of endpoint "' . $endpoint . '" has an "id" field that is not valid'); - $this->test->array($content) - ->hasKey('href', 'The response for the POST route path of endpoint "' . $endpoint . '" does not have an "href" field'); - $this->test->integer(strcasecmp($content['href'], $endpoint . '/' . $content['id'])) - ->isEqualTo(0, 'The response for the POST route path of endpoint "' . $endpoint . '" has an "href" field that is not valid'); + $this->test->assertArrayHasKey('id', $content, 'The response for the POST route path of endpoint "' . $endpoint . '" does not have an "id" field'); + $this->test->assertGreaterThan(0, $content['id'], 'The response for the POST route path of endpoint "' . $endpoint . '" has an "id" field that is not valid'); + $this->test->assertArrayHasKey('href', $content, 'The response for the POST route path of endpoint "' . $endpoint . '" does not have an "href" field'); + $this->test->assertEqualsIgnoringCase($content['href'], $endpoint . '/' . $content['id'], 'The response for the POST route path of endpoint "' . $endpoint . '" has an "href" field that is not valid'); }) ->headers(function ($headers) use (&$new_item_location) { - $this->test->array($headers)->hasKey('Location'); - $this->test->string($headers['Location'])->isNotEmpty(); + $this->test->assertNotEmpty($headers['Location']); $new_item_location = $headers['Location']; }); }); @@ -446,9 +398,9 @@ public function autoTestCRUD(string $endpoint, array $create_params = [], array ->jsonContent(function ($content) use ($create_params) { foreach ($create_params as $key => $value) { if (is_array($content[$key]) && isset($content[$key]['id'])) { - $this->test->variable($content[$key]['id'])->isEqualTo($value); + $this->test->assertEquals($value, $content[$key]['id']); } else { - $this->test->variable($content[$key])->isEqualTo($value); + $this->test->assertEquals($value, $content[$key]); } } }); @@ -474,9 +426,9 @@ public function autoTestCRUD(string $endpoint, array $create_params = [], array ->jsonContent(function ($content) use ($update_params) { foreach ($update_params as $key => $value) { if (is_array($content[$key]) && isset($content[$key]['id'])) { - $this->test->variable($content[$key]['id'])->isEqualTo($value); + $this->test->assertEquals($value, $content[$key]['id']); } else { - $this->test->variable($content[$key])->isEqualTo($value); + $this->test->assertEquals($value, $content[$key]); } } }); @@ -487,7 +439,7 @@ public function autoTestCRUD(string $endpoint, array $create_params = [], array /** @var \HLAPICallAsserter $call */ $call->response ->isOK() - ->jsonContent(fn ($content) => $this->test->variable($content)->isNull()); + ->jsonContent(fn ($content) => $this->test->assertNull($content)); }); $itemtype = $schema['x-itemtype']; @@ -502,9 +454,9 @@ public function autoTestCRUD(string $endpoint, array $create_params = [], array ->jsonContent(function ($content) use ($update_params) { foreach ($update_params as $key => $value) { if (is_array($content[$key]) && isset($content[$key]['id'])) { - $this->test->variable($content[$key]['id'])->isEqualTo($value); + $this->test->assertEquals($value, $content[$key]['id']); } else { - $this->test->variable($content[$key])->isEqualTo($value); + $this->test->assertEquals($value, $content[$key]); } } }); @@ -517,7 +469,7 @@ public function autoTestCRUD(string $endpoint, array $create_params = [], array /** @var \HLAPICallAsserter $call */ $call->response ->isOK() - ->jsonContent(fn ($content) => $this->test->variable($content)->isNull()); + ->jsonContent(fn ($content) => $this->test->assertNull($content)); }); } } @@ -535,7 +487,7 @@ public function autoTestCRUD(string $endpoint, array $create_params = [], array public function autoTestSearch(string $endpoint, array $dataset, string $unique_field = 'name'): self { $this->test->resetSession(); - $this->test->array($dataset)->size->isGreaterThan(2, 'Dataset for endpoint "' . $endpoint . '" must have at least 3 entries'); + $this->test->assertCount(3, $dataset, 'Dataset for endpoint "' . $endpoint . '" must have at least 3 entries'); // Search without authorization should return an error $this->call(new Request('GET', $endpoint), function ($call) { @@ -550,19 +502,19 @@ public function autoTestSearch(string $endpoint, array $dataset, string $unique_ $routes = [...$this->getRoutesForEndpoint($endpoint)]; $search_route = array_filter($routes, static fn ($rp) => in_array('GET', $rp->getRouteMethods()))[0] ?? null; - $this->test->variable($search_route)->isNotNull('No GET route found for endpoint "' . $endpoint . '"'); + $this->test->assertNotNull($search_route, 'No GET route found for endpoint "' . $endpoint . '"'); $response_schema = $this->getRoutePathResponseSchema(route_path: $search_route, method: 'GET', attributes: $search_route->getAttributesFromPath($endpoint)); - $this->test->variable($response_schema)->isNotNull('No response schema found for GET route for endpoint "' . $endpoint . '"'); - $this->test->string($response_schema['type'])->isEqualTo('array', 'Response schema for GET route for endpoint "' . $endpoint . '" is not for an array'); + $this->test->assertNotNull($response_schema, 'No response schema found for GET route for endpoint "' . $endpoint . '"'); + $this->test->assertEquals('array', $response_schema['type'], 'Response schema for GET route for endpoint "' . $endpoint . '" is not for an array'); // Search routes should allow filtering, pagination, and sorting - $this->test->boolean($this->routePathHasParameter($search_route, 'filter', 'query'))->isTrue('No "filter" query parameter found for GET route for endpoint "' . $endpoint . '"'); - $this->test->boolean($this->routePathHasParameter($search_route, 'start', 'query'))->isTrue('No "start" query parameter found for GET route for endpoint "' . $endpoint . '"'); - $this->test->boolean($this->routePathHasParameter($search_route, 'limit', 'query'))->isTrue('No "limit" query parameter found for GET route for endpoint "' . $endpoint . '"'); - $this->test->boolean($this->routePathHasParameter($search_route, 'sort', 'query'))->isTrue('No "sort" query parameter found for GET route for endpoint "' . $endpoint . '"'); + $this->test->assertTrue($this->routePathHasParameter($search_route, 'filter', 'query'), 'No "filter" query parameter found for GET route for endpoint "' . $endpoint . '"'); + $this->test->assertTrue($this->routePathHasParameter($search_route, 'start', 'query'), 'No "start" query parameter found for GET route for endpoint "' . $endpoint . '"'); + $this->test->assertTrue($this->routePathHasParameter($search_route, 'limit', 'query'), 'No "limit" query parameter found for GET route for endpoint "' . $endpoint . '"'); + $this->test->assertTrue($this->routePathHasParameter($search_route, 'sort', 'query'), 'No "sort" query parameter found for GET route for endpoint "' . $endpoint . '"'); // Search routes should specify the ResultFormatterMiddleware to allow optionally returning results as CSV or XML - $this->test->boolean($this->routePathHasMiddleware($search_route, ResultFormatterMiddleware::class))->isTrue('ResultFormatterMiddleware not found on GET route for endpoint "' . $endpoint . '"'); + $this->test->assertTrue($this->routePathHasMiddleware($search_route, ResultFormatterMiddleware::class), 'ResultFormatterMiddleware not found on GET route for endpoint "' . $endpoint . '"'); foreach ($dataset as $i => &$entry) { if (!isset($entry[$unique_field])) { @@ -592,13 +544,13 @@ public function autoTestSearch(string $endpoint, array $dataset, string $unique_ $call->response ->isOK() ->headers(function ($headers) use ($endpoint, $dataset) { - $this->test->array($headers)->hasKey('Content-Range'); + $this->test->assertArrayHasKey('Content-Range', $headers); $content_range = $headers['Content-Range']; [$result_range, $total_count] = explode('/', $content_range); $result_range = explode('-', $result_range); - $this->test->integer((int) $result_range[0])->isEqualTo(0, 'The Content-Range header for endpoint "' . $endpoint . '" does not start at 0 when no pagination parameters are specified (' . $content_range . ')'); - $this->test->integer((int) $result_range[1])->isLessThanOrEqualTo($total_count, 'The Content-Range header for endpoint "' . $endpoint . '" does not have a valid range when no pagination parameters are specified (' . $content_range . ')'); - $this->test->integer((int) $total_count)->isGreaterThanOrEqualTo(count($dataset), 'The Content-Range header for endpoint "' . $endpoint . '" does not have a valid total count when no pagination parameters are specified (' . $content_range . ')'); + $this->test->assertEquals(0, (int) $result_range[0], 'The Content-Range header for endpoint "' . $endpoint . '" does not start at 0 when no pagination parameters are specified (' . $content_range . ')'); + $this->test->assertLessThanOrEqual($total_count, (int) $result_range[1], 'The Content-Range header for endpoint "' . $endpoint . '" does not have a valid range when no pagination parameters are specified (' . $content_range . ')'); + $this->test->assertGreaterThanOrEqual(count($dataset), (int) $total_count, 'The Content-Range header for endpoint "' . $endpoint . '" does not have a valid total count when no pagination parameters are specified (' . $content_range . ')'); }); }); @@ -611,13 +563,13 @@ public function autoTestSearch(string $endpoint, array $dataset, string $unique_ $call->response ->isOK() ->headers(function ($headers) use ($endpoint, $dataset) { - $this->test->array($headers)->hasKey('Content-Range'); + $this->test->assertArrayHasKey('Content-Range', $headers); $content_range = $headers['Content-Range']; [$result_range, $total_count] = explode('/', $content_range); $result_range = explode('-', $result_range); - $this->test->integer((int) $result_range[0])->isEqualTo(1, 'The Content-Range header for endpoint "' . $endpoint . '" does not start at the correct position (' . $content_range . ')'); - $this->test->integer((int) $result_range[1])->isEqualTo(2, 'The Content-Range header for endpoint "' . $endpoint . '" does not have a valid range (' . $content_range . ')'); - $this->test->integer((int) $total_count)->isGreaterThanOrEqualTo(count($dataset), 'The Content-Range header for endpoint "' . $endpoint . '" does not have a valid total count (' . $content_range . ')'); + $this->test->assertEquals(1, (int) $result_range[0], 'The Content-Range header for endpoint "' . $endpoint . '" does not start at the correct position (' . $content_range . ')'); + $this->test->assertEquals(2, (int) $result_range[1], 'The Content-Range header for endpoint "' . $endpoint . '" does not have a valid range (' . $content_range . ')'); + $this->test->assertGreaterThanOrEqual(count($dataset), (int) $total_count, 'The Content-Range header for endpoint "' . $endpoint . '" does not have a valid total count (' . $content_range . ')'); }); }); @@ -634,7 +586,7 @@ public function autoTestSearch(string $endpoint, array $dataset, string $unique_ $fail_msg = 'The response for the GET route path of endpoint "' . $endpoint . '" does not have the correct number of results when filtering by ' . $unique_field; $fail_msg .= ' (filter: ' . $unique_field . '=like=' . $unique_prefix . '*)'; $fail_msg .= "\n" . var_export($content, true); - $this->test->array($content)->hasSize(count($dataset), $fail_msg); + $this->test->assertCount(count($dataset), $content, $fail_msg); }); }); @@ -648,7 +600,7 @@ public function autoTestSearch(string $endpoint, array $dataset, string $unique_ $fail_msg = 'The response for the GET route path of endpoint "' . $endpoint . '" does not have the correct number of results when filtering by ' . $unique_field; $fail_msg .= ' (filter: ' . $unique_field . '==' . $content[0][$unique_field] . ')'; $fail_msg .= "\n" . var_export($content, true); - $this->test->array($content)->hasSize(1, $fail_msg); + $this->test->assertCount(1, $content, $fail_msg); }); }); @@ -670,10 +622,10 @@ public function autoTestSearch(string $endpoint, array $dataset, string $unique_ ->jsonContent(function ($content) use ($sorted_dataset, $endpoint, $sort, $unique_field) { $fail_msg = 'The response for the GET route path of endpoint "' . $endpoint . '" does not have the correct results when sorting with ' . $sort; $fail_msg .= "\n" . var_export($content, true); - $this->test->array($content)->hasSize(count($sorted_dataset), $fail_msg); + $this->test->assertCount(count($sorted_dataset), $content, $fail_msg); // Compare the results with the sorted dataset foreach ($sorted_dataset as $i => $entry) { - $this->test->variable($content[$i][$unique_field])->isEqualTo($entry[$unique_field], $fail_msg); + $this->test->assertEquals($entry[$unique_field], $content[$i][$unique_field], $fail_msg); } }); }); @@ -691,10 +643,10 @@ public function autoTestSearch(string $endpoint, array $dataset, string $unique_ ->jsonContent(function ($content) use ($sorted_dataset, $endpoint, $sort, $unique_field) { $fail_msg = 'The response for the GET route path of endpoint "' . $endpoint . '" does not have the correct results when sorting with ' . $sort; $fail_msg .= "\n" . var_export($content, true); - $this->test->array($content)->hasSize(count($sorted_dataset), $fail_msg); + $this->test->assertCount(count($sorted_dataset), $content, $fail_msg); // Compare the results with the sorted dataset foreach ($sorted_dataset as $i => $entry) { - $this->test->variable($content[$i][$unique_field])->isEqualTo($entry[$unique_field], $fail_msg); + $this->test->assertEquals($entry[$unique_field], $content[$i][$unique_field], $fail_msg); } }); }); @@ -838,10 +790,8 @@ public function isOK(): HLAPIResponseAsserter $response_content = json_decode((string) $this->response->getBody(), true); $fail_msg .= " ($status_code):\n" . var_export($response_content, true); // Status is 200 - 299 - $this->call_asserter->test - ->integer($this->response->getStatusCode())->isGreaterThanOrEqualTo(200, $fail_msg); - $this->call_asserter->test - ->integer($this->response->getStatusCode())->isLessThan(300, $fail_msg); + $this->call_asserter->test->assertGreaterThanOrEqual(200, $status_code, $fail_msg); + $this->call_asserter->test->assertLessThan(300, $status_code, $fail_msg); } return $this; } @@ -851,12 +801,10 @@ public function isUnauthorizedError(): HLAPIResponseAsserter $uri = $this->call_asserter->originalRequest->getUri(); // Status is 401 $this->call_asserter->test - ->integer($this->response->getStatusCode())->isEqualTo(401, 'Status code for call to ' . $uri . ' is not 401'); + ->assertEquals(401, $this->response->getStatusCode(), 'Status code for call to ' . $uri . ' is not 401'); $decoded_content = json_decode((string) $this->response->getBody(), true); - $this->call_asserter->test - ->array($decoded_content)->hasKeys(['title', 'detail', 'status'], 'Response from ' . $uri . ' is not a valid error response'); - $this->call_asserter->test - ->string($decoded_content['status'])->isEqualTo('ERROR_UNAUTHENTICATED', 'Status property in response from ' . $uri . ' is not ERROR_UNAUTHENTICATED'); + $this->call_asserter->test->assertCount(3, array_intersect(['title', 'detail', 'status'], array_keys($decoded_content)), 'Response from ' . $uri . ' is not a valid error response'); + $this->call_asserter->test->assertEquals('ERROR_UNAUTHENTICATED', $decoded_content['status'], 'Status property in response from ' . $uri . ' is not ERROR_UNAUTHENTICATED'); return $this; } @@ -865,12 +813,10 @@ public function isNotFoundError(): HLAPIResponseAsserter $uri = $this->call_asserter->originalRequest->getUri(); // Status is 404 $this->call_asserter->test - ->integer($this->response->getStatusCode())->isEqualTo(404, 'Status code for call to ' . $uri . ' is not 404'); + ->assertEquals(404, $this->response->getStatusCode(), 'Status code for call to ' . $uri . ' is not 404'); $decoded_content = json_decode((string) $this->response->getBody(), true); - $this->call_asserter->test - ->array($decoded_content)->hasKeys(['title', 'detail', 'status'], 'Response from ' . $uri . ' is not a valid error response'); - $this->call_asserter->test - ->string($decoded_content['status'])->isEqualTo('ERROR_ITEM_NOT_FOUND', 'Status property in response from ' . $uri . ' is not ERROR_ITEM_NOT_FOUND'); + $this->call_asserter->test->assertCount(3, array_intersect(['title', 'detail', 'status'], array_keys($decoded_content)), 'Response from ' . $uri . ' is not a valid error response'); + $this->call_asserter->test->assertEquals('ERROR_ITEM_NOT_FOUND', $decoded_content['status'], 'Status property in response from ' . $uri . ' is not ERROR_ITEM_NOT_FOUND'); return $this; } @@ -898,8 +844,7 @@ public function matchesSchema(string|array $schema, string|null $fail_msg = null $fail_msg = $fail_msg ?? 'Response content does not match the schema'; $fail_msg .= ":\n" . var_export($item, true); $fail_msg .= "\n\nSchema:\n" . var_export($schema, true); - $this->call_asserter->test - ->boolean($matches)->isTrue($fail_msg); + $this->call_asserter->test->assertTrue($matches, $fail_msg); } } return $this; @@ -931,14 +876,14 @@ public function compiledPath(callable $fn): self public function isAuthRequired(): self { $this->call_asserter->test - ->boolean($this->routePath->getRouteSecurityLevel() !== Route::SECURITY_NONE)->isTrue('Route does not require authentication'); + ->assertTrue($this->routePath->getRouteSecurityLevel() !== Route::SECURITY_NONE, 'Route does not require authentication'); return $this; } public function isAnonymousAllowed(): self { $this->call_asserter->test - ->boolean($this->routePath->getRouteSecurityLevel() === Route::SECURITY_NONE)->isTrue('Route does not allow anonymous access'); + ->assertTrue($this->routePath->getRouteSecurityLevel() === Route::SECURITY_NONE, 'Route does not allow anonymous access'); return $this; } @@ -947,69 +892,3 @@ public function get(): RoutePath return $this->routePath; } } - -// @codingStandardsIgnoreStart -/** - * Proxy score class to modify the failure data to be able to have more details about the failures. - * By default, atoum reports assertion failures with the file, line, and message of the line in the test class where the assertion was called - * rather than where the asserter was actually called. - * - * This issue can present itself in several ways. First, if a test is in a parent, abstract class, the line for the failure will always be 0. - * If you use a helper method (like we do with the API tests), it will report the line in the test class that called the helper. - */ -class HLAPITestScore extends atoum\atoum\score { - protected $real_score; - public function __construct($real_score = null) - { - parent::__construct(); - $this->real_score = $real_score; - } - - public function addFail($file, $class, $method, $line, $asserter, $reason, $case = null, $dataSetKey = null, $dataSetProvider = null) - { - // Search stack trace for the frame after this function but before the atoum assert call - $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); - while (str_contains($trace[0]['file'], 'atoum')) { - array_shift($trace); - } - // remove one more frame because the asserts are technically part of the test class - array_shift($trace); - $frame = array_shift($trace); - // If the frame refers to a closure, we can use the next frame instead since the closure is probably some magic used by this helper - if (str_ends_with($frame['function'], '{closure}')) { - $frame = array_shift($trace); - } - - $new_asserter = $asserter; - if ($frame !== null && isset($frame['line'], $frame['class'], $frame['function'])) { - $real_line = $frame['line']; - $real_class = $frame['class']; - $real_method = $frame['function']; - - // Replace the $asserter string to display the desired info - $new_asserter = $real_class . '::' . $real_method . ' (line ' . $real_line . ')'; - } - return $this->real_score->addFail($file, $class, $method, $line, $new_asserter, $reason, $case, $dataSetKey, $dataSetProvider); - } - - // Redirect all others - public function __call($name, $arguments) - { - return call_user_func_array([$this->real_score, $name], $arguments); - } - - public function __get($name) - { - return $this->real_score->$name; - } - - public function __set($name, $value) - { - $this->real_score->$name = $value; - } - - public function __isset($name) - { - return isset($this->real_score->$name); - } -} diff --git a/phpunit/bootstrap.php b/phpunit/bootstrap.php index 2ff785718c2..ae4c0ba0911 100644 --- a/phpunit/bootstrap.php +++ b/phpunit/bootstrap.php @@ -83,6 +83,7 @@ //include_once __DIR__ . '/functional/Glpi/ContentTemplates/Parameters/AbstractParameters.php'; include_once __DIR__ . '/AbstractRightsDropdown.php'; include_once __DIR__ . '/CommonDropdown.php'; +include_once __DIR__ . '/HLAPITestCase.php'; loadDataset(); diff --git a/tests/functional/Glpi/Api/HL/Controller/AdministrationController.php b/phpunit/functional/Glpi/Api/HL/Controller/AdministrationControllerTest.php similarity index 81% rename from tests/functional/Glpi/Api/HL/Controller/AdministrationController.php rename to phpunit/functional/Glpi/Api/HL/Controller/AdministrationControllerTest.php index a1131ae1038..939ca0d55fd 100644 --- a/tests/functional/Glpi/Api/HL/Controller/AdministrationController.php +++ b/phpunit/functional/Glpi/Api/HL/Controller/AdministrationControllerTest.php @@ -37,8 +37,9 @@ use Glpi\Api\HL\Controller\AbstractController; use Glpi\Http\Request; +use PHPUnit\Framework\Attributes\DataProvider; -class AdministrationController extends \HLAPITestCase +class AdministrationControllerTest extends \HLAPITestCase { public function testSearchUsers() { @@ -54,13 +55,13 @@ public function testSearchUsers() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->isNotEmpty(); + $this->assertNotEmpty($content); foreach ($content as $v) { - $this->boolean(is_array($v))->isTrue(); - $this->array($v)->hasKeys(['id', 'username', 'realname', 'firstname']); + $this->assertTrue(is_array($v)); + $this->assertCount(4, array_intersect(array_keys($v), ['id', 'username', 'realname', 'firstname'])); // Should never have "name" field as it should be mapped to "username" // Should never pass the password fields to the client - $this->array($v)->notHasKeys(['name', 'password', 'password2']); + $this->assertCount(0, array_intersect(array_keys($v), ['name', 'password', 'password2'])); } }); }); @@ -73,11 +74,11 @@ public function testSearchUsers() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasSize(1); + $this->assertCount(1, $content); $user = $content[0]; - $this->integer($user['id'])->isGreaterThan(0); - $this->string($user['username'])->isEqualTo(TU_USER); - $this->array($user['emails'])->size->isGreaterThanOrEqualTo(1); + $this->assertGreaterThan(0, $user['id']); + $this->assertEquals(TU_USER, $user['username']); + $this->assertGreaterThanOrEqual(1, $user['emails']); }); }); @@ -88,11 +89,11 @@ public function testSearchUsers() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasSize(1); + $this->assertCount(1, $content); $user = $content[0]; - $this->integer($user['id'])->isGreaterThan(0); - $this->string($user['username'])->isEqualTo(TU_USER); - $this->array($user['emails'])->size->isGreaterThanOrEqualTo(1); + $this->assertGreaterThan(0, $user['id']); + $this->assertEquals(TU_USER, $user['username']); + $this->assertGreaterThanOrEqual(1, $user['emails']); }); }); } @@ -125,9 +126,9 @@ public function testUserSearchByEmail() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasSize(1); + $this->assertCount(1, $content); $user = $content[0]; - $this->string($user['username'])->isEqualTo(TU_USER); + $this->assertEquals(TU_USER, $user['username']); }); }); } @@ -169,7 +170,7 @@ public function testSearchProfiles() ]); } - protected function getItemProvider() + public static function getItemProvider() { return [ ['User', getItemByTypeName('User', TU_USER, true)], @@ -179,9 +180,7 @@ protected function getItemProvider() ]; } - /** - * @dataProvider getItemProvider - */ + #[DataProvider('getItemProvider')] public function testGetItem(string $type, int $id) { $this->login('glpi', 'glpi'); @@ -190,8 +189,8 @@ public function testGetItem(string $type, int $id) $call->response ->isOK() ->jsonContent(function ($content) use ($id) { - $this->boolean(is_array($content))->isTrue(); - $this->integer($content['id'])->isEqualTo($id); + $this->assertIsArray($content); + $this->assertEquals($id, $content['id']); }); }); } @@ -204,7 +203,7 @@ public function testGetUserByUsername() $call->response ->isOK() ->jsonContent(function ($content) { - $this->string($content['username'])->isEqualTo(TU_USER); + $this->assertEquals(TU_USER, $content['username']); }); }); } @@ -217,7 +216,7 @@ public function testGetMe() $call->response ->isOK() ->jsonContent(function ($content) { - $this->string($content['username'])->isEqualTo(TU_USER); + $this->assertEquals(TU_USER, $content['username']); }); }); @@ -228,7 +227,7 @@ public function testGetMe() /** @var \HLAPICallAsserter $call */ $call->response->isOK() ->jsonContent(function ($content) { - $this->string($content['username'])->isEqualTo(TU_USER); + $this->assertEquals(TU_USER, $content['username']); }); }); } @@ -241,16 +240,16 @@ public function testGetMyEmails() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->isNotEmpty(); + $this->assertNotEmpty($content); $has_expected_email = false; foreach ($content as $v) { - $this->boolean(is_array($v))->isTrue(); - $this->array($v)->hasKeys(['id', 'email', 'is_default']); + $this->assertIsArray($v); + $this->assertCount(3, array_intersect(array_keys($v), ['id', 'email', 'is_default'])); if ($v['email'] === TU_USER . '@glpi.com') { $has_expected_email = true; } } - $this->boolean($has_expected_email)->isTrue(); + $this->assertTrue($has_expected_email); }); }); } @@ -275,8 +274,8 @@ public function testGetMySpecificEmail() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasKeys(['id', 'email', 'is_default']); - $this->string($content['email'])->isEqualTo(TU_USER . '@glpi.com'); + $this->assertCount(3, array_intersect(array_keys($content), ['id', 'email', 'is_default'])); + $this->assertEquals(TU_USER . '@glpi.com', $content['email']); }); }); @@ -298,7 +297,7 @@ private function addCustomUserPicture(int $user_id, string $picture_path) { global $DB; $picture_path = \Toolbox::savePicture($picture_path, '', true); - $this->variable($picture_path)->isNotFalse(); + $this->assertIsString($picture_path); $DB->update('glpi_users', [ 'id' => $user_id, 'picture' => $picture_path @@ -315,7 +314,7 @@ public function testGetMyPicture() $call->response ->isOK() ->content(function ($content) { - $this->string($content)->isIdenticalTo(file_get_contents(GLPI_ROOT . '/public/pics/picture.png')); + $this->assertEquals(file_get_contents(GLPI_ROOT . '/public/pics/picture.png'), $content); }); }); $this->addCustomUserPicture($_SESSION['glpiID'], GLPI_ROOT . '/tests/fixtures/uploads/foo.png'); @@ -325,7 +324,7 @@ public function testGetMyPicture() $call->response ->isOK() ->jsonContent(function ($content) { - $this->string($content['picture'])->contains('/front/document.send.php'); + $this->assertStringContainsString('/front/document.send.php', $content['picture']); }); }); @@ -334,7 +333,7 @@ public function testGetMyPicture() $call->response ->isOK() ->content(function ($content) { - $this->string($content)->isIdenticalTo(file_get_contents(GLPI_ROOT . '/tests/fixtures/uploads/foo.png')); + $this->assertEquals(file_get_contents(GLPI_ROOT . '/tests/fixtures/uploads/foo.png'), $content); }); }); } @@ -349,7 +348,7 @@ public function testGetUserPictureByID() $call->response ->isOK() ->content(function ($content) { - $this->string($content)->isIdenticalTo(file_get_contents(GLPI_ROOT . '/public/pics/picture.png')); + $this->assertEquals(file_get_contents(GLPI_ROOT . '/public/pics/picture.png'), $content); }); }); $this->addCustomUserPicture($_SESSION['glpiID'], GLPI_ROOT . '/tests/fixtures/uploads/foo.png'); @@ -359,7 +358,7 @@ public function testGetUserPictureByID() $call->response ->isOK() ->content(function ($content) { - $this->string($content)->isIdenticalTo(file_get_contents(GLPI_ROOT . '/tests/fixtures/uploads/foo.png')); + $this->assertEquals(file_get_contents(GLPI_ROOT . '/tests/fixtures/uploads/foo.png'), $content); }); }); } @@ -373,7 +372,7 @@ public function testGetUserPictureByUsername() $call->response ->isOK() ->content(function ($content) { - $this->string($content)->isIdenticalTo(file_get_contents(GLPI_ROOT . '/public/pics/picture.png')); + $this->assertEquals(file_get_contents(GLPI_ROOT . '/public/pics/picture.png'), $content); }); }); $this->addCustomUserPicture($_SESSION['glpiID'], GLPI_ROOT . '/tests/fixtures/uploads/foo.png'); @@ -383,7 +382,7 @@ public function testGetUserPictureByUsername() $call->response ->isOK() ->content(function ($content) { - $this->string($content)->isIdenticalTo(file_get_contents(GLPI_ROOT . '/tests/fixtures/uploads/foo.png')); + $this->assertEquals(file_get_contents(GLPI_ROOT . '/tests/fixtures/uploads/foo.png'), $content); }); }); } @@ -451,10 +450,10 @@ public function testMultisort() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasSize(3); - $this->string($content[0]['username'])->isEqualTo('testuser1'); - $this->string($content[1]['username'])->isEqualTo('testuser3'); - $this->string($content[2]['username'])->isEqualTo('testuser2'); + $this->assertCount(3, $content); + $this->assertEquals('testuser1', $content[0]['username']); + $this->assertEquals('testuser3', $content[1]['username']); + $this->assertEquals('testuser2', $content[2]['username']); }); }); $request->setParameter('sort', 'firstname:desc,username'); @@ -463,10 +462,10 @@ public function testMultisort() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasSize(3); - $this->string($content[0]['username'])->isEqualTo('testuser2'); - $this->string($content[1]['username'])->isEqualTo('testuser1'); - $this->string($content[2]['username'])->isEqualTo('testuser3'); + $this->assertCount(3, $content); + $this->assertEquals('testuser2', $content[0]['username']); + $this->assertEquals('testuser1', $content[1]['username']); + $this->assertEquals('testuser3', $content[2]['username']); }); }); } @@ -517,9 +516,9 @@ public function testGetUsedManagedItems() $call->response ->isOK() ->jsonContent(function ($content) use ($expected_used) { - $this->integer(count($content))->isGreaterThanOrEqualTo(count($expected_used)); + $this->assertGreaterThanOrEqual(count($expected_used), count($content)); foreach ($expected_used as $type => $ids) { - $this->array(array_column(array_filter($content, static fn ($v) => $v['_itemtype'] === $type), 'id'))->containsValues($ids); + $this->assertCount(count($ids), array_intersect(array_column(array_filter($content, static fn ($v) => $v['_itemtype'] === $type), 'id'), $ids)); } }); }); @@ -530,9 +529,9 @@ public function testGetUsedManagedItems() $call->response ->isOK() ->jsonContent(function ($content) use ($expected_managed) { - $this->integer(count($content))->isGreaterThanOrEqualTo(count($expected_managed)); + $this->assertGreaterThanOrEqual(count($expected_managed), count($content)); foreach ($expected_managed as $type => $ids) { - $this->array(array_column(array_filter($content, static fn ($v) => $v['_itemtype'] === $type), 'id'))->containsValues($ids); + $this->assertCount(count($ids), array_intersect(array_column(array_filter($content, static fn ($v) => $v['_itemtype'] === $type), 'id'), $ids)); } }); }); diff --git a/tests/functional/Glpi/Api/HL/Controller/AssetController.php b/phpunit/functional/Glpi/Api/HL/Controller/AssetControllerTest.php similarity index 83% rename from tests/functional/Glpi/Api/HL/Controller/AssetController.php rename to phpunit/functional/Glpi/Api/HL/Controller/AssetControllerTest.php index 02d763880f9..6296f58f09b 100644 --- a/tests/functional/Glpi/Api/HL/Controller/AssetController.php +++ b/phpunit/functional/Glpi/Api/HL/Controller/AssetControllerTest.php @@ -36,8 +36,9 @@ namespace tests\units\Glpi\Api\HL\Controller; use Glpi\Http\Request; +use PHPUnit\Framework\Attributes\DataProvider; -class AssetController extends \HLAPITestCase +class AssetControllerTest extends \HLAPITestCase { public function testIndex() { @@ -50,17 +51,17 @@ public function testIndex() $call->response ->isOK() ->jsonContent(function ($content) use ($types) { - $this->array($content)->size->isGreaterThanOrEqualTo(count($types)); + $this->assertGreaterThanOrEqual(count($types), count($content)); foreach ($content as $asset) { - $this->array($asset)->hasKeys(['itemtype', 'name', 'href']); - $this->string($asset['name'])->isNotEmpty(); - $this->string($asset['href'])->isEqualTo('/Assets/' . $asset['itemtype']); + $this->assertNotEmpty($asset['itemtype']); + $this->assertNotEmpty($asset['name']); + $this->assertEquals('/Assets/' . $asset['itemtype'], $asset['href']); } }); }); } - public function searchProvider() + public static function searchProvider() { return [ ['schema' => 'Computer', 'filters' => [], 'expected' => ['count' => ['>=', 9]]], @@ -91,10 +92,7 @@ public function searchProvider() ['schema' => 'SoftwareLicense', 'filters' => [], 'expected' => ['count' => ['>', 0]]], ]; } - - /** - * @dataProvider searchProvider - */ + #[DataProvider('searchProvider')] public function testSearch(string $schema, array $filters, array $expected) { $this->login(); @@ -133,7 +131,7 @@ public function testAutoSearch() $call->response ->isOK() ->jsonContent(function ($content) use ($dataset) { - $this->array($content)->size->isGreaterThanOrEqualTo(1); + $this->assertGreaterThanOrEqual(1, count($content)); foreach ($content as $asset) { $to_skip = ['SoftwareLicense', 'Unmanaged']; if (in_array($asset['itemtype'], $to_skip, true)) { @@ -145,7 +143,7 @@ public function testAutoSearch() }); } - protected function getItemProvider() + public static function getItemProvider() { return [ ['schema' => 'Computer', 'id' => getItemByTypeName('Computer', '_test_pc01', true), 'expected' => ['fields' => ['name' => '_test_pc01']]], @@ -158,9 +156,7 @@ protected function getItemProvider() ]; } - /** - * @dataProvider getItemProvider - */ + #[DataProvider('getItemProvider')] public function testGetItem(string $schema, int $id, array $expected) { $this->login(); @@ -176,7 +172,7 @@ public function testGetItem(string $schema, int $id, array $expected) }); } - protected function createUpdateDeleteItemProvider() + public static function createUpdateDeleteItemProvider() { $types = [ 'Computer', 'Monitor', 'NetworkEquipment', 'Peripheral', 'Phone', 'Printer', @@ -196,9 +192,7 @@ protected function createUpdateDeleteItemProvider() } } - /** - * @dataProvider createUpdateDeleteItemProvider - */ + #[DataProvider('createUpdateDeleteItemProvider')] public function testCreateUpdateDeleteItem(string $schema, array $fields) { $this->api->autoTestCRUD('/Assets/' . $schema, $fields); @@ -229,7 +223,7 @@ public function testCRUDRackItem() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->isEmpty(); + $this->assertEmpty($content); }); }); @@ -244,7 +238,7 @@ public function testCRUDRackItem() $call->response ->isOK() ->headers(function ($headers) use (&$rackitem_location) { - $this->array($headers)->hasKey('Location'); + $this->assertNotEmpty($headers['Location']); $rackitem_location = $headers['Location']; }); }); @@ -255,9 +249,9 @@ public function testCRUDRackItem() $call->response ->isOK() ->jsonContent(function ($content) use ($computer_id) { - $this->array($content)->size->isEqualTo(1); - $this->string($content[0]['itemtype'])->isEqualTo('Computer'); - $this->integer($content[0]['items_id'])->isEqualTo($computer_id); + $this->assertCount(1, $content); + $this->assertEquals('Computer', $content[0]['itemtype']); + $this->assertEquals($computer_id, $content[0]['items_id']); }); }); @@ -293,7 +287,7 @@ public function testCRUDRackItem() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->isEmpty(); + $this->assertEmpty($content); }); }); } @@ -310,15 +304,15 @@ public function testSearchAllAssets() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->size->isGreaterThanOrEqualTo(3); + $this->assertGreaterThanOrEqual(3, count($content)); $count_by_type = []; // Count by the _itemtype field in each element foreach ($content as $item) { $count_by_type[$item['_itemtype']] = ($count_by_type[$item['_itemtype']] ?? 0) + 1; } - $this->integer($count_by_type['Computer'])->isGreaterThanOrEqualTo(1); - $this->integer($count_by_type['Monitor'])->isGreaterThanOrEqualTo(1); - $this->integer($count_by_type['Printer'])->isGreaterThanOrEqualTo(1); + $this->assertGreaterThanOrEqual(1, $count_by_type['Computer']); + $this->assertGreaterThanOrEqual(1, $count_by_type['Monitor']); + $this->assertGreaterThanOrEqual(1, $count_by_type['Printer']); }); }); } @@ -329,7 +323,7 @@ public function testCRUDSoftwareVersion() // Create a software $software = new \Software(); - $this->integer($software_id = $software->add([ + $this->assertGreaterThan(0, $software_id = $software->add([ 'name' => __FUNCTION__, 'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true), ])); @@ -343,8 +337,8 @@ public function testCRUDSoftwareVersion() $call->response ->isOK() ->headers(function ($headers) use ($software_id, &$new_item_location) { - $this->array($headers)->hasKey('Location'); - $this->string($headers['Location'])->startWith("/Assets/Software/$software_id/Version/"); + $this->assertNotEmpty($headers['Location']); + $this->assertStringStartsWith("/Assets/Software/$software_id/Version/", $headers['Location']); $new_item_location = $headers['Location']; }); }); @@ -355,8 +349,8 @@ public function testCRUDSoftwareVersion() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasKey('name'); - $this->string($content['name'])->isEqualTo('1.0'); + $this->assertNotEmpty($content['name']); + $this->assertEquals('1.0', $content['name']); }); }); @@ -391,24 +385,24 @@ public function testDropdownTranslations() { $this->login(); $state = new \State(); - $this->integer($state_id = $state->add([ + $this->assertGreaterThan(0, $state_id = $state->add([ 'name' => 'Test', 'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true), - ]))->isGreaterThan(0); + ])); $computer = new \Computer(); - $this->integer($computer_id = $computer->add([ + $this->assertGreaterThan(0, $computer_id = $computer->add([ 'name' => 'Test', 'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true), 'states_id' => $state_id, - ]))->isGreaterThan(0); + ])); $dropdown_translation = new \DropdownTranslation(); - $this->integer($dropdown_translation->add([ + $this->assertGreaterThan(0, $dropdown_translation->add([ 'items_id' => $state_id, 'itemtype' => 'State', 'language' => 'fr_FR', 'field' => 'name', 'value' => 'Essai', - ]))->isGreaterThan(0); + ])); // Get and verify $this->api->call(new Request('GET', '/Assets/Computer/' . $computer_id), function ($call) use ($state_id) { @@ -416,9 +410,8 @@ public function testDropdownTranslations() $call->response ->isOK() ->jsonContent(function ($content) use ($state_id) { - $this->array($content)->hasKey('status'); - $this->array($content['status'])->hasKey('name'); - $this->string($content['status']['name'])->isEqualTo('Test'); + $this->assertEquals($state_id, $content['status']['id']); + $this->assertEquals('Test', $content['status']['name']); }); }); // Change language and verify @@ -430,9 +423,8 @@ public function testDropdownTranslations() $call->response ->isOK() ->jsonContent(function ($content) use ($state_id) { - $this->array($content)->hasKey('status'); - $this->array($content['status'])->hasKey('name'); - $this->string($content['status']['name'])->isEqualTo('Essai'); + $this->assertEquals($state_id, $content['status']['id']); + $this->assertEquals('Essai', $content['status']['name']); }); }); } @@ -441,16 +433,16 @@ public function testMissingDropdownTranslation() { $this->login(); $state = new \State(); - $this->integer($state_id = $state->add([ + $this->assertGreaterThan(0, $state_id = $state->add([ 'name' => 'Test', 'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true), - ]))->isGreaterThan(0); + ])); $computer = new \Computer(); - $this->integer($computer_id = $computer->add([ + $this->assertGreaterThan(0, $computer_id = $computer->add([ 'name' => 'Test', 'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true), 'states_id' => $state_id, - ]))->isGreaterThan(0); + ])); // Get and verify $this->api->call(new Request('GET', '/Assets/Computer/' . $computer_id), function ($call) use ($state_id) { @@ -458,9 +450,8 @@ public function testMissingDropdownTranslation() $call->response ->isOK() ->jsonContent(function ($content) use ($state_id) { - $this->array($content)->hasKey('status'); - $this->array($content['status'])->hasKey('name'); - $this->string($content['status']['name'])->isEqualTo('Test'); + $this->assertEquals($state_id, $content['status']['id']); + $this->assertEquals('Test', $content['status']['name']); }); }); // Change language and verify the default name is returned instead of null @@ -470,9 +461,8 @@ public function testMissingDropdownTranslation() $call->response ->isOK() ->jsonContent(function ($content) use ($state_id) { - $this->array($content)->hasKey('status'); - $this->array($content['status'])->hasKey('name'); - $this->string($content['status']['name'])->isEqualTo('Test'); + $this->assertEquals($state_id, $content['status']['id']); + $this->assertEquals('Test', $content['status']['name']); }); }); } @@ -503,9 +493,9 @@ public function testGetItemInfocom() $call->response ->isOK() ->jsonContent(function ($content) use ($computers_id) { - $this->string($content['itemtype'])->isEqualTo('Computer'); - $this->integer($content['items_id'])->isEqualTo($computers_id); - $this->string($content['date_buy'])->isEqualTo('2020-01-01'); + $this->assertEquals('Computer', $content['itemtype']); + $this->assertEquals($computers_id, $content['items_id']); + $this->assertEquals('2020-01-01', $content['date_buy']); }); }); } @@ -524,8 +514,7 @@ public function testCreateInOtherEntities() $call->response ->isOK() ->headers(function ($headers) use (&$new_location) { - $this->array($headers)->hasKey('Location'); - $this->string($headers['Location'])->startWith('/Assets/Computer/'); + $this->assertStringStartsWith('/Assets/Computer/', $headers['Location']); $new_location = $headers['Location']; }); }); @@ -535,9 +524,7 @@ public function testCreateInOtherEntities() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasKey('entity'); - $this->array($content['entity'])->hasKey('name'); - $this->string($content['entity']['name'])->isEqualTo('_test_child_1'); + $this->assertEquals('_test_child_1', $content['entity']['name']); }); }); } diff --git a/tests/functional/Glpi/Api/HL/Controller/ComponentController.php b/phpunit/functional/Glpi/Api/HL/Controller/ComponentControllerTest.php similarity index 83% rename from tests/functional/Glpi/Api/HL/Controller/ComponentController.php rename to phpunit/functional/Glpi/Api/HL/Controller/ComponentControllerTest.php index 06be666b7a9..c613744bc73 100644 --- a/tests/functional/Glpi/Api/HL/Controller/ComponentController.php +++ b/phpunit/functional/Glpi/Api/HL/Controller/ComponentControllerTest.php @@ -37,8 +37,9 @@ use Glpi\Api\HL\Router; use Glpi\Http\Request; +use PHPUnit\Framework\Attributes\DataProvider; -class ComponentController extends \HLAPITestCase +class ComponentControllerTest extends \HLAPITestCase { public function testIndex() { @@ -51,17 +52,17 @@ public function testIndex() $call->response ->isOK() ->jsonContent(function ($content) use ($types) { - $this->array($content)->size->isGreaterThanOrEqualTo(count($types)); + $this->assertGreaterThanOrEqual(count($types), count($content)); foreach ($content as $component) { - $this->array($component)->hasKeys(['itemtype', 'name', 'href']); - $this->string($component['name'])->isNotEmpty(); - $this->string($component['href'])->startWith('/Components/'); + $this->assertNotEmpty($component['itemtype']); + $this->assertNotEmpty($component['name']); + $this->assertStringStartsWith('/Components/', $component['href']); } }); }); } - protected function deviceTypeProvider() + public static function deviceTypeProvider() { $types = [ 'Battery', 'Camera', 'Case', 'Controller', 'Drive', 'Firmware', 'GenericDevice', 'GraphicCard', @@ -74,9 +75,7 @@ protected function deviceTypeProvider() } } - /** - * @dataProvider deviceTypeProvider - */ + #[DataProvider('deviceTypeProvider')] public function testCRUD(string $type) { $this->api->autoTestCRUD('/Components/' . $type, [ @@ -85,9 +84,7 @@ public function testCRUD(string $type) ]); } - /** - * @dataProvider deviceTypeProvider - */ + #[DataProvider('deviceTypeProvider')] public function testGetComponentsOfType(string $type) { global $DB; @@ -98,7 +95,7 @@ public function testGetComponentsOfType(string $type) //ignore SIMCard for now because sim cards not in a device are impossible to exist if ($type === 'SIMCard') { - $this->boolean(true)->isTrue(); + $this->assertTrue(true); return; } @@ -112,8 +109,7 @@ public function testGetComponentsOfType(string $type) $call->response ->isOK() ->headers(function ($headers) use ($type, &$new_item_location) { - $this->array($headers)->hasKey('Location'); - $this->string($headers['Location'])->startWith("/Components/" . $type); + $this->assertStringStartsWith("/Components/" . $type, $headers['Location']); $new_item_location = $headers['Location']; }); }); @@ -125,7 +121,7 @@ public function testGetComponentsOfType(string $type) $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->isEmpty(); + $this->assertEmpty($content); }); }); @@ -140,12 +136,12 @@ public function testGetComponentsOfType(string $type) 'FROM' => $schema['x-itemtype']::getTable(), 'WHERE' => ['designation' => $type . $func_name], ])->current()['id']; - $this->integer($items_id)->isGreaterThan(0); + $this->assertGreaterThan(0, $items_id); // Add a component of this type - $this->integer($item->add([ + $this->assertGreaterThan(0, $item->add([ $device_fk => $items_id, - ]))->isGreaterThan(0); + ])); // There should now be one component of this type $this->api->call(new Request('GET', $items_location), function ($call) use ($type) { @@ -153,7 +149,7 @@ public function testGetComponentsOfType(string $type) $call->response ->isOK() ->jsonContent(function ($content) use ($type) { - $this->array($content)->size->isEqualTo(1); + $this->assertCount(1, $content); $join_key = $type; // If there is a lowercase letter followed by an uppercase letter, we need to add an underscore between them // Ex: PowerSupply => Power_Supply @@ -163,7 +159,8 @@ public function testGetComponentsOfType(string $type) $join_key = preg_replace('/([A-Z]{2,})([A-Z])/', '$1_$2', $join_key); // Make lowercase $join_key = strtolower($join_key); - $this->array($content[0])->hasKeys(['id', $join_key]); + $this->assertArrayHasKey('id', $content[0]); + $this->assertArrayHasKey($join_key, $content[0]); }); }); } diff --git a/tests/functional/Glpi/Api/HL/Controller/CoreController.php b/phpunit/functional/Glpi/Api/HL/Controller/CoreControllerTest.php similarity index 75% rename from tests/functional/Glpi/Api/HL/Controller/CoreController.php rename to phpunit/functional/Glpi/Api/HL/Controller/CoreControllerTest.php index b685b51a2ac..8c2f126d440 100644 --- a/tests/functional/Glpi/Api/HL/Controller/CoreController.php +++ b/phpunit/functional/Glpi/Api/HL/Controller/CoreControllerTest.php @@ -37,10 +37,11 @@ use Glpi\Asset\Asset_PeripheralAsset; use Glpi\Http\Request; +use PHPUnit\Framework\Attributes\DataProvider; -class CoreController extends \HLAPITestCase +class CoreControllerTest extends \HLAPITestCase { - protected function routeMatchProvider() + public static function routeMatchProvider() { return [ [new Request('GET', '/Session'), true], @@ -51,12 +52,10 @@ protected function routeMatchProvider() ]; } - /** - * @dataProvider routeMatchProvider - */ + #[DataProvider('routeMatchProvider')] public function testRouteMatches(Request $request, bool $expected) { - $this->api->hasMatch($request)->isEqualTo($expected); + $this->assertEquals($expected, $this->api->hasMatch($request)); } public function testOptionsRoute() @@ -67,9 +66,9 @@ public function testOptionsRoute() $call->response ->isOK() ->headers(function ($headers) { - $this->string($headers['Allow'])->isIdenticalTo('GET'); + $this->assertEquals('GET', $headers['Allow']); }) - ->status(fn ($status) => $this->integer($status)->isEqualTo(204)); + ->status(fn ($status) => $this->assertEquals(204, $status)); }); $this->api->call(new Request('OPTIONS', '/Administration/User'), function ($call) { @@ -77,9 +76,9 @@ public function testOptionsRoute() $call->response ->isOK() ->headers(function ($headers) { - $this->array($headers['Allow'])->containsValues(['GET', 'POST']); + $this->assertCount(2, array_intersect($headers['Allow'], ['GET', 'POST'])); }) - ->status(fn ($status) => $this->integer($status)->isEqualTo(204)); + ->status(fn ($status) => $this->assertEquals(204, $status)); }); } @@ -91,22 +90,20 @@ public function testHeadMethod() $call->response ->isOK() ->headers(function ($headers) { - $this->string($headers['Content-Type'])->isEqualTo('application/json'); + $this->assertEquals('application/json', $headers['Content-Type']); }) - ->content(fn ($content) => $this->string($content)->isEmpty()); + ->content(fn ($content) => $this->assertEmpty($content)); }); } - protected function responseContentSchemaProvider() + public static function responseContentSchemaProvider() { return [ [new Request('GET', '/Session'), 'Session'] ]; } - /** - * @dataProvider responseContentSchemaProvider - */ + #[DataProvider('responseContentSchemaProvider')] public function testResponseContentSchema(Request $request, string $schema_name) { $this->login(); @@ -128,13 +125,13 @@ public function testTransferEntity() 'name' => 'Computer 1', 'entities_id' => $root_entity, ]); - $this->integer($computers_id_1)->isGreaterThan(0); + $this->assertGreaterThan(0, $computers_id_1); $computers_id_2 = $computer->add([ 'name' => 'Computer 2', 'entities_id' => $root_entity, ]); - $this->integer($computers_id_2)->isGreaterThan(0); + $this->assertGreaterThan(0, $computers_id_2); // Create a monitor to test transfer options are passed correctly (keep_dc_monitor) $monitor = new \Monitor(); @@ -142,7 +139,7 @@ public function testTransferEntity() 'name' => 'Monitor 1', 'entities_id' => $root_entity, ]); - $this->integer($monitors_id)->isGreaterThan(0); + $this->assertGreaterThan(0, $monitors_id); // Connect the monitor to the computer $connection_item = new Asset_PeripheralAsset(); @@ -152,7 +149,7 @@ public function testTransferEntity() 'itemtype_peripheral' => \Monitor::class, 'items_id_peripheral' => $monitors_id, ]); - $this->integer($connection_item_id)->isGreaterThan(0); + $this->assertGreaterThan(0, $connection_item_id); // Create 2 new entities (not using API) $entity = new \Entity(); @@ -160,13 +157,13 @@ public function testTransferEntity() 'name' => 'Entity 1', 'entities_id' => $root_entity, ]); - $this->integer($entities_id_1)->isGreaterThan(0); + $this->assertGreaterThan(0, $entities_id_1); $entities_id_2 = $entity->add([ 'name' => 'Entity 2', 'entities_id' => $root_entity, ]); - $this->integer($entities_id_2)->isGreaterThan(0); + $this->assertGreaterThan(0, $entities_id_2); $transfer_records = [ [ @@ -197,31 +194,31 @@ public function testTransferEntity() $this->api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(200)) - ->content(fn ($content) => $this->string($content)->isEmpty()); + ->status(fn ($status) => $this->assertEquals(200, $status)) + ->content(fn ($content) => $this->assertEmpty($content)); }); // Check the computers have been transferred - $this->boolean($computer->getFromDB($computers_id_1))->isTrue(); - $this->integer($computer->fields['entities_id'])->isEqualTo($entities_id_1); + $this->assertTrue($computer->getFromDB($computers_id_1)); + $this->assertEquals($entities_id_1, $computer->fields['entities_id']); - $this->boolean($computer->getFromDB($computers_id_2))->isTrue(); - $this->integer($computer->fields['entities_id'])->isEqualTo($entities_id_2); + $this->assertTrue($computer->getFromDB($computers_id_2)); + $this->assertEquals($entities_id_2, $computer->fields['entities_id']); // Verify computer 1 has a monitor connection, and computer 2 doesn't - $this->boolean($connection_item->getFromDBByCrit([ + $this->assertTrue($connection_item->getFromDBByCrit([ 'itemtype_asset' => \Computer::class, 'items_id_asset' => $computers_id_1, 'itemtype_peripheral' => \Monitor::class, 'items_id_peripheral' => $monitors_id, - ]) === true)->isTrue(); + ]) === true); - $this->boolean($connection_item->getFromDBByCrit([ + $this->assertFalse($connection_item->getFromDBByCrit([ 'itemtype_asset' => \Computer::class, 'items_id_asset' => $computers_id_2, 'itemtype_peripheral' => \Monitor::class, 'items_id_peripheral' => $monitors_id, - ]) === true)->isFalse(); + ]) === true); } public function testOAuthPasswordGrant() @@ -235,7 +232,7 @@ public function testOAuthPasswordGrant() 'is_active' => 1, 'is_confidential' => 1, ]); - $this->integer($client_id)->isGreaterThan(0); + $this->assertGreaterThan(0, $client_id); // get client ID and secret $it = $DB->request([ @@ -243,7 +240,7 @@ public function testOAuthPasswordGrant() 'FROM' => \OAuthClient::getTable(), 'WHERE' => ['id' => $client_id], ]); - $this->integer($it->count())->isEqualTo(1); + $this->assertCount(1, $it); $client_data = $it->current(); $auth_data = [ 'grant_type' => 'password', @@ -259,7 +256,7 @@ public function testOAuthPasswordGrant() $this->api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(401)); + ->status(fn ($status) => $this->assertEquals(401, $status)); }); $client->update([ @@ -271,12 +268,11 @@ public function testOAuthPasswordGrant() $this->api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(200)) + ->status(fn ($status) => $this->assertEquals(200, $status)) ->jsonContent(function ($content) { - $this->array($content)->hasKeys(['access_token', 'expires_in', 'token_type']); - $this->string($content['token_type'])->isEqualTo('Bearer'); - $this->string($content['access_token'])->isNotEmpty(); - $this->integer($content['expires_in'])->isGreaterThan(0); + $this->assertEquals('Bearer', $content['token_type']); + $this->assertNotEmpty($content['access_token']); + $this->assertGreaterThan(0, $content['expires_in']); }); }); } @@ -293,7 +289,7 @@ public function testOAuthPasswordGrantHeader() 'is_confidential' => 1, 'grants' => ['password'] ]); - $this->integer($client_id)->isGreaterThan(0); + $this->assertGreaterThan(0, $client_id); // get client ID and secret $it = $DB->request([ @@ -301,7 +297,7 @@ public function testOAuthPasswordGrantHeader() 'FROM' => \OAuthClient::getTable(), 'WHERE' => ['id' => $client_id], ]); - $this->integer($it->count())->isEqualTo(1); + $this->assertCount(1, $it); $client_data = $it->current(); $auth_data = [ 'grant_type' => 'password', @@ -316,12 +312,11 @@ public function testOAuthPasswordGrantHeader() $this->api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(200)) + ->status(fn ($status) => $this->assertEquals(200, $status)) ->jsonContent(function ($content) { - $this->array($content)->hasKeys(['access_token', 'expires_in', 'token_type']); - $this->string($content['token_type'])->isEqualTo('Bearer'); - $this->string($content['access_token'])->isNotEmpty(); - $this->integer($content['expires_in'])->isGreaterThan(0); + $this->assertEquals('Bearer', $content['token_type']); + $this->assertNotEmpty($content['access_token']); + $this->assertGreaterThan(0, $content['expires_in']); }); }); } @@ -338,7 +333,7 @@ public function testOAuthAuthCodeGrant() 'is_active' => 1, 'is_confidential' => 1, ]); - $this->integer($client_id)->isGreaterThan(0); + $this->assertGreaterThan(0, $client_id); $client->update([ 'id' => $client_id, @@ -352,7 +347,7 @@ public function testOAuthAuthCodeGrant() 'FROM' => \OAuthClient::getTable(), 'WHERE' => ['id' => $client_id], ]); - $this->integer($it->count())->isEqualTo(1); + $this->assertCount(1, $it); $client_data = $it->current(); // Test authorize endpoint @@ -367,10 +362,10 @@ public function testOAuthAuthCodeGrant() $this->api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(302)) + ->status(fn ($status) => $this->assertEquals(302, $status)) ->headers(function ($headers) { global $CFG_GLPI; - $this->string($headers['Location'])->matches('/^' . preg_quote($CFG_GLPI['url_base'], '/') . '\/\?redirect=/'); + $this->assertMatchesRegularExpression('/^' . preg_quote($CFG_GLPI['url_base'], '/') . '\/\?redirect=/', $headers['Location']); }); }); } @@ -386,7 +381,7 @@ public function testOAuthClientCredentialsGrant(): void 'is_active' => 1, 'is_confidential' => 1, ]); - $this->integer($client_id)->isGreaterThan(0); + $this->assertGreaterThan(0, $client_id); // get client ID and secret $it = $DB->request([ @@ -394,7 +389,7 @@ public function testOAuthClientCredentialsGrant(): void 'FROM' => \OAuthClient::getTable(), 'WHERE' => ['id' => $client_id], ]); - $this->integer($it->count())->isEqualTo(1); + $this->assertCount(1, $it); $client_data = $it->current(); $auth_data = [ 'grant_type' => 'client_credentials', @@ -408,7 +403,7 @@ public function testOAuthClientCredentialsGrant(): void $this->api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(401)); + ->status(fn ($status) => $this->assertEquals(401, $status)); }); $client->update([ @@ -421,12 +416,11 @@ public function testOAuthClientCredentialsGrant(): void $this->api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(200)) + ->status(fn ($status) => $this->assertEquals(200, $status)) ->jsonContent(function ($content) { - $this->array($content)->hasKeys(['access_token', 'expires_in', 'token_type']); - $this->string($content['token_type'])->isEqualTo('Bearer'); - $this->string($content['access_token'])->isNotEmpty(); - $this->integer($content['expires_in'])->isGreaterThan(0); + $this->assertEquals('Bearer', $content['token_type']); + $this->assertNotEmpty($content['access_token']); + $this->assertGreaterThan(0, $content['expires_in']); }); }); } diff --git a/tests/functional/Glpi/Api/HL/Controller/GraphQLController.php b/phpunit/functional/Glpi/Api/HL/Controller/GraphQLControllerTest.php similarity index 59% rename from tests/functional/Glpi/Api/HL/Controller/GraphQLController.php rename to phpunit/functional/Glpi/Api/HL/Controller/GraphQLControllerTest.php index 40668cf5a3a..893e348bc01 100644 --- a/tests/functional/Glpi/Api/HL/Controller/GraphQLController.php +++ b/phpunit/functional/Glpi/Api/HL/Controller/GraphQLControllerTest.php @@ -38,7 +38,7 @@ use Glpi\Http\Request; use Glpi\OAuth\Server; -class GraphQLController extends \HLAPITestCase +class GraphQLControllerTest extends \HLAPITestCase { public function testGraphQLListSchemas() { @@ -48,25 +48,21 @@ public function testGraphQLListSchemas() $this->api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(200)) + ->status(fn ($status) => $this->assertEquals(200, $status)) ->jsonContent(function ($content) { - $this->array($content)->hasKey('data'); - $this->array($content['data'])->hasKey('__schema'); - $this->array($content['data']['__schema'])->hasKey('types'); - $this->array($content['data']['__schema']['types'])->size->isGreaterThan(150); + $this->assertGreaterThan(150, $content['data']['__schema']['types']); $types = $content['data']['__schema']['types']; $some_expected = ['Computer', 'Ticket', 'User', 'PrinterModel', 'FirmwareType']; $found = []; foreach ($types as $type) { - $this->array($type)->hasKey('name'); - $this->array($type)->notHasKey('description'); - $this->array($type)->notHasKey('fields'); - $this->string($type['name'])->isNotEmpty(); + $this->assertArrayNotHasKey('description', $type); + $this->assertArrayNotHasKey('fields', $type); + $this->assertNotEmpty($type['name']); if (in_array($type['name'], $some_expected, true)) { $found[] = $type['name']; } } - $this->array($found)->size->isEqualTo(count($some_expected)); + $this->assertCount(count($some_expected), $found); }); }); @@ -74,13 +70,13 @@ public function testGraphQLListSchemas() $this->api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(200)) + ->status(fn ($status) => $this->assertEquals(200, $status)) ->jsonContent(function ($content) { $types = $content['data']['__schema']['types']; foreach ($types as $type) { - $this->array($type)->hasKey('name'); - $this->array($type)->hasKey('description'); - $this->array($type)->notHasKey('fields'); + $this->assertArrayHasKey('name', $type); + $this->assertArrayHasKey('description', $type); + $this->assertArrayNotHasKey('fields', $type); } }); }); @@ -89,13 +85,13 @@ public function testGraphQLListSchemas() $this->api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(200)) + ->status(fn ($status) => $this->assertEquals(200, $status)) ->jsonContent(function ($content) { $types = $content['data']['__schema']['types']; foreach ($types as $type) { - $this->array($type)->hasKey('name'); - $this->array($type)->notHasKey('description'); - $this->array($type)->hasKey('fields'); + $this->assertArrayHasKey('name', $type); + $this->assertArrayNotHasKey('description', $type); + $this->assertArrayHasKey('fields', $type); } }); }); @@ -109,15 +105,12 @@ public function testGetComputer() $this->api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(200)) + ->status(fn ($status) => $this->assertEquals(200, $status)) ->jsonContent(function ($content) { - $this->array($content)->hasKey('data'); - $this->array($content['data'])->hasSize(1); - $this->array($content['data']['Computer'])->hasSize(1); - $this->array($content['data']['Computer'][0])->hasKey('id'); - $this->array($content['data']['Computer'][0])->hasKey('name'); - $this->integer($content['data']['Computer'][0]['id'])->isEqualTo(1); - $this->string($content['data']['Computer'][0]['name'])->isEqualTo('_test_pc01'); + $this->assertCount(1, $content['data']); + $this->assertCount(1, $content['data']['Computer']); + $this->assertEquals(1, $content['data']['Computer'][0]['id']); + $this->assertEquals('_test_pc01', $content['data']['Computer'][0]['name']); }); }); } @@ -130,11 +123,10 @@ public function testGetComputers() $this->api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(200)) + ->status(fn ($status) => $this->assertEquals(200, $status)) ->jsonContent(function ($content) { - $this->array($content)->hasKey('data'); - $this->array($content['data'])->hasSize(1); - $this->array($content['data']['Computer'])->size->isGreaterThan(2); + $this->assertCount(1, $content['data']); + $this->assertGreaterThan(2, count($content['data']['Computer'])); }); }); } @@ -147,11 +139,10 @@ public function testGetComputersWithFilter() $this->api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(200)) + ->status(fn ($status) => $this->assertEquals(200, $status)) ->jsonContent(function ($content) { - $this->array($content)->hasKey('data'); - $this->array($content['data'])->hasSize(1); - $this->array($content['data']['Computer'])->size->isEqualTo(9); + $this->assertCount(1, $content['data']); + $this->assertCount(9, $content['data']['Computer']); }); }); } @@ -163,35 +154,33 @@ public function testFullSchemaReplacement() // Create some data just to ensure there is something to return $printer_model = new \PrinterModel(); - $this->integer($printer_model->add([ + $this->assertGreaterThan(0, $printer_model->add([ 'name' => '_test_printer_model', 'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true) - ]))->isGreaterThan(0); + ])); $cartridge_item = new \CartridgeItem(); - $this->integer($cartridge_item->add([ + $this->assertGreaterThan(0, $cartridge_item->add([ 'name' => '_test_cartridge_item', 'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true) - ]))->isGreaterThan(0); - $this->integer((new \CartridgeItem_PrinterModel())->add([ + ])); + $this->assertGreaterThan(0, (new \CartridgeItem_PrinterModel())->add([ 'cartridgeitems_id' => $cartridge_item->getID(), 'printermodels_id' => $printer_model->getID() - ]))->isGreaterThan(0); + ])); // product_number is not available this way via the REST API, but should be available here as the partial schema gets replaced by the full schema $request = new Request('POST', '/GraphQL', [], 'query { CartridgeItem { id name printer_models { name product_number } } }'); $this->api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(200)) + ->status(fn ($status) => $this->assertEquals(200, $status)) ->jsonContent(function ($content) { - $this->array($content)->hasKey('data'); - $this->array($content['data'])->hasSize(1); - $this->array($content['data']['CartridgeItem'][0])->hasKey('id'); - $this->array($content['data']['CartridgeItem'][0])->hasKey('name'); - $this->array($content['data']['CartridgeItem'][0])->hasKey('printer_models'); - $this->array($content['data']['CartridgeItem'][0]['printer_models'])->size->isGreaterThan(0); - $this->array($content['data']['CartridgeItem'][0]['printer_models'][0])->hasKey('name'); - $this->array($content['data']['CartridgeItem'][0]['printer_models'][0])->hasKey('product_number'); + $this->assertCount(1, $content['data']); + $this->assertArrayHasKey('id', $content['data']['CartridgeItem'][0]); + $this->assertArrayHasKey('name', $content['data']['CartridgeItem'][0]); + $this->assertGreaterThan(0, count($content['data']['CartridgeItem'][0]['printer_models'])); + $this->assertArrayHasKey('name', $content['data']['CartridgeItem'][0]['printer_models'][0]); + $this->assertArrayHasKey('product_number', $content['data']['CartridgeItem'][0]['printer_models'][0]); }); }); } @@ -203,18 +192,18 @@ public function testFullSchemaReplacement() public function testGetStateVisibilities() { $state = new \State(); - $this->integer($states_id = $state->add([ + $this->assertGreaterThan(0, $states_id = $state->add([ 'name' => __FUNCTION__, 'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true), 'is_visible_computer' => 1, 'is_visible_monitor' => 0 - ]))->isGreaterThan(0); + ])); $computer = new \Computer(); - $this->integer($computers_id = $computer->add([ + $this->assertGreaterThan(0, $computers_id = $computer->add([ 'name' => __FUNCTION__, 'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true), 'states_id' => $states_id - ]))->isGreaterThan(0); + ])); $this->login(); $request = new Request('POST', '/GraphQL', [], <<api->call($request, function ($call) { /** @var \HLAPICallAsserter $call */ $call->response - ->status(fn ($status) => $this->integer($status)->isEqualTo(200)) + ->status(fn ($status) => $this->assertEquals(200, $status)) ->jsonContent(function ($content) { - $this->array($content['data'])->hasSize(1); - $this->array($content['data']['Computer'])->hasSize(1); - $this->array($content['data']['Computer'][0])->hasKey('id'); - $this->array($content['data']['Computer'][0])->hasKey('name'); - $this->array($content['data']['Computer'][0])->hasKey('status'); - $this->array($content['data']['Computer'][0]['status'])->hasKey('name'); - $this->boolean($content['data']['Computer'][0]['status']['visibilities']['computer'])->isTrue(); - $this->boolean($content['data']['Computer'][0]['status']['visibilities']['monitor'])->isFalse(); + $this->assertCount(1, $content['data']); + $this->assertCount(1, $content['data']['Computer']); + $this->assertArrayHasKey('id', $content['data']['Computer'][0]); + $this->assertArrayHasKey('name', $content['data']['Computer'][0]); + $this->assertArrayHasKey('status', $content['data']['Computer'][0]); + $this->assertArrayHasKey('name', $content['data']['Computer'][0]['status']); + $this->assertTrue($content['data']['Computer'][0]['status']['visibilities']['computer']); + $this->assertFalse($content['data']['Computer'][0]['status']['visibilities']['monitor']); }); }); } diff --git a/tests/functional/Glpi/Api/HL/Controller/ITILController.php b/phpunit/functional/Glpi/Api/HL/Controller/ITILControllerTest.php similarity index 86% rename from tests/functional/Glpi/Api/HL/Controller/ITILController.php rename to phpunit/functional/Glpi/Api/HL/Controller/ITILControllerTest.php index 566fa058ef8..0630b427f71 100644 --- a/tests/functional/Glpi/Api/HL/Controller/ITILController.php +++ b/phpunit/functional/Glpi/Api/HL/Controller/ITILControllerTest.php @@ -37,7 +37,7 @@ use Glpi\Http\Request; -class ITILController extends \HLAPITestCase +class ITILControllerTest extends \HLAPITestCase { public function testCreateGetUpdateDelete() { @@ -71,9 +71,7 @@ public function testCreateGetUpdateDeleteFollowup() $call->response ->isOK() ->headers(function ($headers) use ($itil_type, &$itil_base_path) { - $this->array($headers)->hasKey('Location'); - $this->string($headers['Location'])->isNotEmpty(); - $this->string($headers['Location'])->contains('/Assistance/' . $itil_type); + $this->assertStringContainsString('/Assistance/' . $itil_type, $headers['Location']); $itil_base_path = $headers['Location']; }); }); @@ -101,9 +99,7 @@ public function testCreateGetUpdateDeleteTask() $call->response ->isOK() ->headers(function ($headers) use ($itil_type, &$itil_base_path) { - $this->array($headers)->hasKey('Location'); - $this->string($headers['Location'])->isNotEmpty(); - $this->string($headers['Location'])->contains('/Assistance/' . $itil_type); + $this->assertStringContainsString('/Assistance/' . $itil_type, $headers['Location']); $itil_base_path = $headers['Location']; }); }); @@ -131,9 +127,7 @@ public function testGetTimeline() $call->response ->isOK() ->headers(function ($headers) use ($itil_type, &$itil_base_path) { - $this->array($headers)->hasKey('Location'); - $this->string($headers['Location'])->isNotEmpty(); - $this->string($headers['Location'])->contains('/Assistance/' . $itil_type); + $this->assertStringContainsString('/Assistance/' . $itil_type, $headers['Location']); $itil_base_path = $headers['Location']; }); }); @@ -157,7 +151,7 @@ public function testGetTimeline() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->size->isGreaterThanOrEqualTo(4); + $this->assertGreaterThanOrEqual(4, count($content)); // Ensure there are 2 items with type=Task and 2 items with type=Followup $remaining_matches = [ 'Task' => ['test0' => 1, 'test1' => 1], @@ -166,7 +160,7 @@ public function testGetTimeline() $tasks = array_filter($content, static function ($item) { return $item['type'] === 'Task'; }); - $this->array($tasks)->size->isIdenticalTo(2); + $this->assertCount(2, $tasks); foreach ($tasks as $task) { unset($remaining_matches['Task'][$task['item']['content']]); } @@ -174,13 +168,13 @@ public function testGetTimeline() $fups = array_filter($content, static function ($item) { return $item['type'] === 'Followup'; }); - $this->array($fups)->size->isIdenticalTo(2); + $this->assertCount(2, $fups); foreach ($fups as $fup) { unset($remaining_matches['Followup'][$fup['item']['content']]); } - $this->array($remaining_matches['Task'])->isEmpty(); - $this->array($remaining_matches['Followup'])->isEmpty(); + $this->assertEmpty($remaining_matches['Task']); + $this->assertEmpty($remaining_matches['Followup']); }); }); } @@ -247,12 +241,12 @@ public function testCRUDRecurringITIL() // Create a ITIL template $template_class = $itil_type . 'Template'; $template = new $template_class(); - $this->integer($templates_id = $template->add([ + $this->assertGreaterThan(0, $templates_id = $template->add([ 'name' => __FUNCTION__, 'content' => 'test', 'is_recursive' => 1, 'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true), - ]))->isGreaterThan(0); + ])); $this->api->autoTestCRUD('/Assistance/Recurring' . $itil_type, [ 'name' => $func_name, @@ -268,11 +262,11 @@ public function testCRUDRecurringITIL() public function testBlockOverridingParentItem() { $ticket = new \Ticket(); - $this->integer($tickets_id = $ticket->add([ + $this->assertGreaterThan(0, $tickets_id = $ticket->add([ 'name' => __FUNCTION__, 'content' => 'test', 'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true), - ]))->isGreaterThan(0); + ])); $fup = new \ITILFollowup(); $task = new \TicketTask(); @@ -282,50 +276,50 @@ public function testBlockOverridingParentItem() $document_item = new \Document_Item(); // Create a followup - $this->integer($fup_id = $fup->add([ + $this->assertGreaterThan(0, $fup_id = $fup->add([ 'name' => __FUNCTION__, 'content' => 'test', 'itemtype' => 'Ticket', 'items_id' => $tickets_id, - ]))->isGreaterThan(0); + ])); // Create a task - $this->integer($task_id = $task->add([ + $this->assertGreaterThan(0, $task_id = $task->add([ 'name' => __FUNCTION__, 'content' => 'test', 'tickets_id' => $tickets_id, - ]))->isGreaterThan(0); + ])); // Create a solution - $this->integer($solution_id = $solution->add([ + $this->assertGreaterThan(0, $solution_id = $solution->add([ 'name' => __FUNCTION__, 'content' => 'test', 'itemtype' => 'Ticket', 'items_id' => $tickets_id, - ]))->isGreaterThan(0); + ])); // Create a validation - $this->integer($validation_id = $validation->add([ + $this->assertGreaterThan(0, $validation_id = $validation->add([ 'name' => __FUNCTION__, 'content' => 'test', 'tickets_id' => $tickets_id, 'itemtype_target' => 'User', 'items_id_target' => 2 - ]))->isGreaterThan(0); + ])); // Create a document - $this->integer($document_id = $document->add([ + $this->assertGreaterThan(0, $document_id = $document->add([ 'name' => __FUNCTION__, 'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true), - ]))->isGreaterThan(0); + ])); // Link the document to the ticket - $this->integer($document_item_id = $document_item->add([ + $this->assertGreaterThan(0, $document_item_id = $document_item->add([ 'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true), 'documents_id' => $document_id, 'itemtype' => 'Ticket', 'items_id' => $tickets_id, - ]))->isGreaterThan(0); + ])); // Need to login to use the API $this->login('glpi', 'glpi'); @@ -343,8 +337,8 @@ public function testBlockOverridingParentItem() /** @var \HLAPICallAsserter $call */ $call->response->isOK(); $call->response->jsonContent(function ($content) use ($tickets_id) { - $this->integer($content['items_id'])->isIdenticalTo($tickets_id); - $this->string($content['itemtype'])->isIdenticalTo('Ticket'); + $this->assertEquals($tickets_id, $content['items_id']); + $this->assertEquals('Ticket', $content['itemtype']); }); }); @@ -360,7 +354,7 @@ public function testBlockOverridingParentItem() /** @var \HLAPICallAsserter $call */ $call->response->isOK(); $call->response->jsonContent(function ($content) use ($tickets_id) { - $this->integer($content['tickets_id'])->isIdenticalTo($tickets_id); + $this->assertEquals($tickets_id, $content['tickets_id']); }); }); @@ -377,8 +371,8 @@ public function testBlockOverridingParentItem() /** @var \HLAPICallAsserter $call */ $call->response->isOK(); $call->response->jsonContent(function ($content) use ($tickets_id) { - $this->integer($content['items_id'])->isIdenticalTo($tickets_id); - $this->string($content['itemtype'])->isIdenticalTo('Ticket'); + $this->assertEquals($tickets_id, $content['items_id']); + $this->assertEquals('Ticket', $content['itemtype']); }); }); @@ -394,7 +388,7 @@ public function testBlockOverridingParentItem() /** @var \HLAPICallAsserter $call */ $call->response->isOK(); $call->response->jsonContent(function ($content) use ($tickets_id) { - $this->integer($content['tickets_id'])->isIdenticalTo($tickets_id); + $this->assertEquals($tickets_id, $content['tickets_id']); }); }); @@ -411,8 +405,8 @@ public function testBlockOverridingParentItem() /** @var \HLAPICallAsserter $call */ $call->response->isOK(); $call->response->jsonContent(function ($content) use ($tickets_id) { - $this->integer($content['items_id'])->isIdenticalTo($tickets_id); - $this->string($content['itemtype'])->isIdenticalTo('Ticket'); + $this->assertEquals($tickets_id, $content['items_id']); + $this->assertEquals('Ticket', $content['itemtype']); }); }); } diff --git a/tests/functional/Glpi/Api/HL/Controller/ManagementController.php b/phpunit/functional/Glpi/Api/HL/Controller/ManagementControllerTest.php similarity index 92% rename from tests/functional/Glpi/Api/HL/Controller/ManagementController.php rename to phpunit/functional/Glpi/Api/HL/Controller/ManagementControllerTest.php index 8ce32f95a17..15a18e92324 100644 --- a/tests/functional/Glpi/Api/HL/Controller/ManagementController.php +++ b/phpunit/functional/Glpi/Api/HL/Controller/ManagementControllerTest.php @@ -37,7 +37,7 @@ use Glpi\Http\Request; -class ManagementController extends \HLAPITestCase +class ManagementControllerTest extends \HLAPITestCase { public function testCreateGetUpdateDelete() { @@ -55,6 +55,6 @@ public function testDocumentDownload() { $this->login(); // Not sure we can mock a file upload to actually test the download. At least we need to check the endpoint exists. - $this->api->hasMatch(new Request('GET', '/Management/Document/1/Download')); + $this->assertTrue($this->api->hasMatch(new Request('GET', '/Management/Document/1/Download'))); } } diff --git a/tests/functional/Glpi/Api/HL/Controller/ProjectController.php b/phpunit/functional/Glpi/Api/HL/Controller/ProjectControllerTest.php similarity index 85% rename from tests/functional/Glpi/Api/HL/Controller/ProjectController.php rename to phpunit/functional/Glpi/Api/HL/Controller/ProjectControllerTest.php index 1ee2bafe5bb..46c98f65e4b 100644 --- a/tests/functional/Glpi/Api/HL/Controller/ProjectController.php +++ b/phpunit/functional/Glpi/Api/HL/Controller/ProjectControllerTest.php @@ -37,7 +37,7 @@ use Glpi\Http\Request; -class ProjectController extends \HLAPITestCase +class ProjectControllerTest extends \HLAPITestCase { public function testCreateGetUpdateDelete() { @@ -60,13 +60,10 @@ public function testCreateGetUpdateDeleteTask() $call->response ->isOK() ->headers(function ($headers) { - $this->array($headers)->hasKey('Location'); - $this->string($headers['Location'])->isNotEmpty(); - $this->string($headers['Location'])->contains('/Project'); + $this->assertStringContainsString('/Project', $headers['Location']); }) ->jsonContent(function ($content) use (&$projects_id) { - $this->array($content)->hasKey('id'); - $this->integer($content['id'])->isGreaterThan(0); + $this->assertGreaterThan(0, $content['id']); $projects_id = $content['id']; }); }); @@ -80,9 +77,7 @@ public function testCreateGetUpdateDeleteTask() $call->response ->isOK() ->headers(function ($headers) use (&$new_item_location) { - $this->array($headers)->hasKey('Location'); - $this->string($headers['Location'])->isNotEmpty(); - $this->string($headers['Location'])->contains("/Project/Task"); + $this->assertStringContainsString('/Project/Task', $headers['Location']); $new_item_location = $headers['Location']; }); }); @@ -93,7 +88,7 @@ public function testCreateGetUpdateDeleteTask() $call->response ->isOK() ->jsonContent(function ($content) { - $this->string($content['content'])->isIdenticalTo('test'); + $this->assertEquals('test', $content['content']); }); }); @@ -111,7 +106,7 @@ public function testCreateGetUpdateDeleteTask() $call->response ->isOK() ->jsonContent(function ($content) { - $this->string($content['content'])->isIdenticalTo('test2'); + $this->assertEquals('test2', $content['content']); }); }); diff --git a/tests/functional/Glpi/Api/HL/Controller/ReportController.php b/phpunit/functional/Glpi/Api/HL/Controller/ReportControllerTest.php similarity index 90% rename from tests/functional/Glpi/Api/HL/Controller/ReportController.php rename to phpunit/functional/Glpi/Api/HL/Controller/ReportControllerTest.php index 93296febb40..cab458a715e 100644 --- a/tests/functional/Glpi/Api/HL/Controller/ReportController.php +++ b/phpunit/functional/Glpi/Api/HL/Controller/ReportControllerTest.php @@ -37,7 +37,7 @@ use Glpi\Http\Request; -class ReportController extends \HLAPITestCase +class ReportControllerTest extends \HLAPITestCase { public function testListStatisticReports() { @@ -49,32 +49,32 @@ public function testListStatisticReports() ->isOK() ->matchesSchema('StatReport[]') ->jsonContent(function ($content) { - $this->array($content)->size->isGreaterThan(7); + $this->assertGreaterThan(7, count($content)); $tested = 0; foreach ($content as $report) { if (in_array($report['report_type'], ['Global', 'Asset'], true) && in_array($report['assistance_type'], ['Ticket', 'Change', 'Problem'], true)) { - $this->array($report['report_group_fields'])->isEmpty(); + $this->assertEmpty($report['report_group_fields']); $tested++; } else if ($report['report_type'] === 'Characteristics' && in_array($report['assistance_type'], ['Ticket', 'Change', 'Problem'], true)) { - $this->array($report['report_group_fields'])->hasKeys([ + $this->assertCount(17, array_intersect(array_keys($report['report_group_fields']), [ 'user', 'users_id_recipient', 'group', 'group_tree', 'usertitles_id', 'usercategories_id', 'itilcategories_id', 'itilcategories_tree', 'urgency', 'impact', 'priority', 'solutiontypes_id', 'technician', 'technician_followup', 'groups_id_assign', 'groups_tree_assign', 'suppliers_id_assign' - ]); + ])); $tested++; } else if ($report['report_type'] === 'AssetCharacteristics' && in_array($report['assistance_type'], ['Ticket', 'Change', 'Problem'], true)) { - $this->array($report['report_group_fields'])->hasKeys([ + $this->assertCount(22, array_intersect(array_keys($report['report_group_fields']), [ 'ComputerType', 'ComputerModel', 'OperatingSystem', 'Location', 'DeviceBattery', 'DeviceCamera', 'DeviceCase', 'DeviceControl', 'DeviceDrive', 'DeviceFirmware', 'DeviceGeneric', 'DeviceGraphicCard', 'DeviceHardDrive', 'DeviceMemory', 'DeviceNetworkCard', 'DevicePci', 'DevicePowerSupply', 'DeviceProcessor', 'DeviceSensor', 'DeviceSimcard', 'DeviceSoundCard', 'DeviceMotherboard' - ]); + ])); $tested++; } } - $this->integer($tested)->isEqualTo(12); + $this->assertEquals(12, $tested); }); }); } @@ -102,7 +102,7 @@ public function testGetITILStats() /** @var \HLAPICallAsserter $call */ $call->response ->status(fn ($status) => $status === 400) - ->jsonContent(fn ($content) => $this->array($content)->isIdenticalTo([ + ->jsonContent(fn ($content) => $this->assertEquals([ 'status' => 'ERROR_INVALID_PARAMETER', 'title' => 'One or more parameters are invalid', 'detail' => null, @@ -112,7 +112,7 @@ public function testGetITILStats() 'message' => 'Missing parameter: field', ] ] - ])); + ], $content)); }); $request = new Request('GET', "/Assistance/Stat/$itil_type/Characteristics"); $request->setParameter('field', 'user'); @@ -148,7 +148,7 @@ public function testGetAssetCharacteristicsStats() /** @var \HLAPICallAsserter $call */ $call->response ->status(fn ($status) => $status === 400) - ->jsonContent(fn ($content) => $this->array($content)->isIdenticalTo([ + ->jsonContent(fn ($content) => $this->assertEquals([ 'status' => 'ERROR_INVALID_PARAMETER', 'title' => 'One or more parameters are invalid', 'detail' => null, @@ -158,7 +158,7 @@ public function testGetAssetCharacteristicsStats() 'message' => 'Missing parameter: field', ] ] - ])); + ], $content)); }); $request = new Request('GET', "/Assistance/Stat/$itil_type/AssetCharacteristics"); $request->setParameter('field', 'user'); diff --git a/tests/functional/Glpi/Api/HL/Controller/RuleController.php b/phpunit/functional/Glpi/Api/HL/Controller/RuleControllerTest.php similarity index 78% rename from tests/functional/Glpi/Api/HL/Controller/RuleController.php rename to phpunit/functional/Glpi/Api/HL/Controller/RuleControllerTest.php index 046ed21e185..20fe3da64a0 100644 --- a/tests/functional/Glpi/Api/HL/Controller/RuleController.php +++ b/phpunit/functional/Glpi/Api/HL/Controller/RuleControllerTest.php @@ -35,9 +35,11 @@ namespace tests\units\Glpi\Api\HL\Controller; +use Glpi\Api\HL\Middleware\InternalAuthMiddleware; use Glpi\Http\Request; +use PHPUnit\Framework\Attributes\DataProvider; -class RuleController extends \HLAPITestCase +class RuleControllerTest extends \HLAPITestCase { protected function getRuleCollections() { @@ -56,13 +58,13 @@ public function testAccess() $rule_ticket_right = $_SESSION['glpiactiveprofile']['rule_ticket']; $_SESSION['glpiactiveprofile']['rule_ticket'] = 0; - $this->api->getRouter()->registerAuthMiddleware(new \Glpi\Api\HL\Middleware\InternalAuthMiddleware()); + $this->api->getRouter()->registerAuthMiddleware(new InternalAuthMiddleware()); $this->api->call(new Request('GET', '/Rule/Collection'), function ($call) { /** @var \HLAPICallAsserter $call */ $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->isNotEmpty(); + $this->assertNotEmpty($content); $has_ticket_rule = false; foreach ($content as $collection) { if ($collection['rule_type'] === 'Ticket') { @@ -70,7 +72,7 @@ public function testAccess() break; } } - $this->boolean($has_ticket_rule)->isFalse(); + $this->assertFalse($has_ticket_rule); }); }, false); // false here avoids initializing a new temporary session and instead uses the InternalAuthMiddleware @@ -82,7 +84,7 @@ public function testAccess() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->isNotEmpty(); + $this->assertNotEmpty($content); $has_ticket_rule = false; foreach ($content as $collection) { if ($collection['rule_type'] === 'Ticket') { @@ -90,7 +92,7 @@ public function testAccess() break; } } - $this->boolean($has_ticket_rule)->isTrue(); + $this->assertTrue($has_ticket_rule); }); }, false); // false here avoids initializing a new temporary session and instead uses the InternalAuthMiddleware } @@ -105,12 +107,13 @@ public function testListCollections() ->isOK() ->jsonContent(function ($content) { $types = array_column($content, 'rule_type'); - $this->array($types)->containsValues($this->getRuleCollections()); + $rule_collections = $this->getRuleCollections(); + $this->assertCount(count($rule_collections), array_intersect($rule_collections, $types)); }); }); } - protected function listRuleCriteriaConditionsProvider() + public static function listRuleCriteriaConditionsProvider() { return [ [ @@ -155,9 +158,7 @@ protected function listRuleCriteriaConditionsProvider() ]; } - /** - * @dataProvider listRuleCriteriaConditionsProvider - */ + #[DataProvider('listRuleCriteriaConditionsProvider')] public function testListRuleCriteriaConditions($type, $conditions) { $this->login(); @@ -171,18 +172,18 @@ public function testListRuleCriteriaConditions($type, $conditions) foreach ($conditions as $id => $condition) { foreach ($content as $item) { if ($item['id'] === $id) { - $this->string($item['description'])->isIdenticalTo($condition['description']); - $this->array($item['fields'])->containsValues($condition['fields']); + $this->assertEquals($condition['description'], $item['description']); + $this->assertCount(count($condition['fields']), array_intersect($condition['fields'], $item['fields'])); $tested[] = $id; } } } - $this->array($tested)->hasSize(count($conditions)); + $this->assertCount(count($conditions), $tested); }); }); } - protected function listRuleCriteriaCriteriaProvider() + public static function listRuleCriteriaCriteriaProvider() { return [ [ @@ -215,9 +216,7 @@ protected function listRuleCriteriaCriteriaProvider() ]; } - /** - * @dataProvider listRuleCriteriaCriteriaProvider - */ + #[DataProvider('listRuleCriteriaCriteriaProvider')] public function testListRuleCriteriaCriteria($type, $criteria) { $this->login(); @@ -231,17 +230,17 @@ public function testListRuleCriteriaCriteria($type, $criteria) foreach ($criteria as $id => $name) { foreach ($content as $item) { if ($item['id'] === $id) { - $this->string($item['name'])->isIdenticalTo($name); + $this->assertEquals($name, $item['name']); $tested[] = $id; } } } - $this->array($tested)->hasSize(count($criteria)); + $this->assertCount(count($criteria), $tested); }); }); } - protected function listRuleActionTypesProvider() + public static function listRuleActionTypesProvider() { return [ [ @@ -269,9 +268,7 @@ protected function listRuleActionTypesProvider() ]; } - /** - * @dataProvider listRuleActionTypesProvider - */ + #[DataProvider('listRuleActionTypesProvider')] public function testListActionTypes($type, $action_types) { $this->login(); @@ -285,18 +282,18 @@ public function testListActionTypes($type, $action_types) foreach ($action_types as $id => $name) { foreach ($content as $item) { if ($item['id'] === $id) { - $this->string($item['name'])->isIdenticalTo($name); - $this->array($item['fields'])->isNotEmpty(); + $this->assertEquals($name, $item['name']); + $this->assertNotEmpty($item['fields']); $tested[] = $id; } } } - $this->array($tested)->hasSize(count($action_types)); + $this->assertCount(count($action_types), $tested); }); }); } - protected function listRuleActionFieldsProvider() + public static function listRuleActionFieldsProvider() { return [ [ @@ -326,9 +323,7 @@ protected function listRuleActionFieldsProvider() ]; } - /** - * @dataProvider listRuleActionFieldsProvider - */ + #[DataProvider('listRuleActionFieldsProvider')] public function testListActionFields($type, $fields) { $this->login(); @@ -342,13 +337,13 @@ public function testListActionFields($type, $fields) foreach ($fields as $id => $name) { foreach ($content as $item) { if ($item['id'] === $id) { - $this->string($item['name'])->isIdenticalTo($name); - $this->array($item['action_types'])->isNotEmpty(); + $this->assertEquals($name, $item['name']); + $this->assertNotEmpty($item['action_types']); $tested[] = $id; } } } - $this->array($tested)->hasSize(count($fields)); + $this->assertCount(count($fields), $tested); }); }); } @@ -370,8 +365,7 @@ public function testCRUDRules() $call->response ->isOK() ->headers(function ($headers) use ($collection, &$new_url) { - $this->array($headers)->hasKey('Location'); - $this->string($headers['Location'])->startWith("/Rule/Collection/{$collection}/Rule"); + $this->assertStringStartsWith("/Rule/Collection/{$collection}/Rule", $headers['Location']); $new_url = $headers['Location']; }); }); @@ -382,8 +376,7 @@ public function testCRUDRules() $call->response ->isOK() ->jsonContent(function ($content) use ($collection) { - $this->array($content)->hasKeys(['name']); - $this->string($content['name'])->isEqualTo("testCRUDRules{$collection}"); + $this->assertEquals("testCRUDRules{$collection}", $content['name']); }); }); @@ -395,8 +388,7 @@ public function testCRUDRules() $call->response ->isOK() ->jsonContent(function ($content) use ($collection) { - $this->array($content)->hasKeys(['name']); - $this->string($content['name'])->isEqualTo("testCRUDRules{$collection}2"); + $this->assertEquals("testCRUDRules{$collection}2", $content['name']); }); }); @@ -420,11 +412,11 @@ public function testCRUDRuleCriteria() $this->login(); $rule = new \Rule(); - $this->integer($rules_id = $rule->add([ + $this->assertGreaterThan(0, $rules_id = $rule->add([ 'entities_id' => $this->getTestRootEntity(true), 'name' => 'testCRUDRuleCriteria', 'sub_type' => 'RuleTicket', - ]))->isGreaterThan(0); + ])); // Create $request = new Request('POST', "/Rule/Collection/Ticket/Rule/{$rules_id}/Criteria"); @@ -437,8 +429,7 @@ public function testCRUDRuleCriteria() $call->response ->isOK() ->headers(function ($headers) use ($rules_id, &$new_url) { - $this->array($headers)->hasKey('Location'); - $this->string($headers['Location'])->startWith("/Rule/Collection/Ticket/Rule/{$rules_id}/Criteria"); + $this->assertStringStartsWith("/Rule/Collection/Ticket/Rule/{$rules_id}/Criteria", $headers['Location']); $new_url = $headers['Location']; }); }); @@ -449,10 +440,9 @@ public function testCRUDRuleCriteria() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasKeys(['criteria', 'condition', 'pattern']); - $this->string($content['criteria'])->isEqualTo('name'); - $this->integer($content['condition'])->isEqualTo(0); - $this->string($content['pattern'])->isEqualTo('testCRUDRuleCriteria'); + $this->assertEquals('name', $content['criteria']); + $this->assertEquals(0, $content['condition']); + $this->assertEquals('testCRUDRuleCriteria', $content['pattern']); }); }); @@ -464,10 +454,9 @@ public function testCRUDRuleCriteria() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasKeys(['criteria', 'condition', 'pattern']); - $this->string($content['criteria'])->isEqualTo('name'); - $this->integer($content['condition'])->isEqualTo(0); - $this->string($content['pattern'])->isEqualTo('testCRUDRuleCriteria2'); + $this->assertEquals('name', $content['criteria']); + $this->assertEquals(0, $content['condition']); + $this->assertEquals('testCRUDRuleCriteria2', $content['pattern']); }); }); @@ -490,11 +479,11 @@ public function testCRUDRuleAction() $this->login(); $rule = new \Rule(); - $this->integer($rules_id = $rule->add([ + $this->assertGreaterThan(0, $rules_id = $rule->add([ 'entities_id' => $this->getTestRootEntity(true), 'name' => 'testCRUDRuleAction', 'sub_type' => 'RuleTicket', - ]))->isGreaterThan(0); + ])); // Create $request = new Request('POST', "/Rule/Collection/Ticket/Rule/{$rules_id}/Action"); @@ -507,8 +496,7 @@ public function testCRUDRuleAction() $call->response ->isOK() ->headers(function ($headers) use ($rules_id, &$new_url) { - $this->array($headers)->hasKey('Location'); - $this->string($headers['Location'])->startWith("/Rule/Collection/Ticket/Rule/{$rules_id}/Action"); + $this->assertStringStartsWith("/Rule/Collection/Ticket/Rule/{$rules_id}/Action", $headers['Location']); $new_url = $headers['Location']; }); }); @@ -519,10 +507,9 @@ public function testCRUDRuleAction() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasKeys(['field', 'action_type', 'value']); - $this->string($content['field'])->isEqualTo('name'); - $this->string($content['action_type'])->isEqualTo('assign'); - $this->string($content['value'])->isEqualTo('testCRUDRuleAction'); + $this->assertEquals('name', $content['field']); + $this->assertEquals('assign', $content['action_type']); + $this->assertEquals('testCRUDRuleAction', $content['value']); }); }); @@ -534,10 +521,9 @@ public function testCRUDRuleAction() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasKeys(['field', 'action_type', 'value']); - $this->string($content['field'])->isEqualTo('name'); - $this->string($content['action_type'])->isEqualTo('assign'); - $this->string($content['value'])->isEqualTo('testCRUDRuleAction2'); + $this->assertEquals('name', $content['field']); + $this->assertEquals('assign', $content['action_type']); + $this->assertEquals('testCRUDRuleAction2', $content['value']); }); }); @@ -570,8 +556,7 @@ public function testAddRuleSpecificRanking() $call->response ->isOK() ->headers(function ($headers) use (&$new_url) { - $this->array($headers)->hasKey('Location'); - $this->string($headers['Location'])->startWith("/Rule/Collection/Ticket/Rule"); + $this->assertStringStartsWith("/Rule/Collection/Ticket/Rule", $headers['Location']); $new_url = $headers['Location']; }); }); @@ -581,9 +566,8 @@ public function testAddRuleSpecificRanking() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasKeys(['name', 'ranking']); - $this->string($content['name'])->isEqualTo("testCRUDRulesRuleTicket"); - $this->integer($content['ranking'])->isEqualTo(1); + $this->assertEquals("testCRUDRulesRuleTicket", $content['name']); + $this->assertEquals(1, $content['ranking']); }); }); } @@ -603,8 +587,7 @@ public function testAddRuleInvalidRanking() $call->response ->isOK() ->headers(function ($headers) use (&$new_url) { - $this->array($headers)->hasKey('Location'); - $this->string($headers['Location'])->startWith("/Rule/Collection/Ticket/Rule"); + $this->assertStringStartsWith("/Rule/Collection/Ticket/Rule", $headers['Location']); $new_url = $headers['Location']; }); }); @@ -615,9 +598,8 @@ public function testAddRuleInvalidRanking() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasKeys(['name', 'ranking']); - $this->string($content['name'])->isEqualTo("testCRUDRulesRuleTicket"); - $this->integer($content['ranking'])->isNotEqualTo(-1); + $this->assertEquals("testCRUDRulesRuleTicket", $content['name']); + $this->assertGreaterThanOrEqual(0, $content['ranking']); }); }); } @@ -636,8 +618,7 @@ public function testUpdateRuleSpecificRanking() $call->response ->isOK() ->headers(function ($headers) use (&$new_url) { - $this->array($headers)->hasKey('Location'); - $this->string($headers['Location'])->startWith("/Rule/Collection/Ticket/Rule"); + $this->assertStringStartsWith("/Rule/Collection/Ticket/Rule", $headers['Location']); $new_url = $headers['Location']; }); }); @@ -650,9 +631,8 @@ public function testUpdateRuleSpecificRanking() $call->response ->isOK() ->jsonContent(function ($content) { - $this->array($content)->hasKeys(['name', 'ranking']); - $this->string($content['name'])->isEqualTo("testCRUDRulesRuleTicket"); - $this->integer($content['ranking'])->isEqualTo(0); + $this->assertEquals("testCRUDRulesRuleTicket", $content['name']); + $this->assertEquals(0, $content['ranking']); }); }); } diff --git a/tests/functional/Glpi/Api/HL/Doc/Schema.php b/phpunit/functional/Glpi/Api/HL/Doc/SchemaTest.php similarity index 86% rename from tests/functional/Glpi/Api/HL/Doc/Schema.php rename to phpunit/functional/Glpi/Api/HL/Doc/SchemaTest.php index 8d65b745bdb..529d4cf602b 100644 --- a/tests/functional/Glpi/Api/HL/Doc/Schema.php +++ b/phpunit/functional/Glpi/Api/HL/Doc/SchemaTest.php @@ -37,10 +37,11 @@ use GLPITestCase; use Glpi\Api\HL\Doc; +use PHPUnit\Framework\Attributes\DataProvider; -class Schema extends GLPITestCase +class SchemaTest extends GLPITestCase { - protected function schemaArrayProvider() + public static function schemaArrayProvider() { return [ [ @@ -66,19 +67,15 @@ enum: ['a', 'b', 'c'], ]; } - /** - * @dataProvider schemaArrayProvider - */ + #[DataProvider('schemaArrayProvider')] public function testToArray($schema, $array) { - $this->array($schema->toArray())->isIdenticalTo($array); + $this->assertEquals($array, $schema->toArray()); } - /** - * @dataProvider schemaArrayProvider - */ + #[DataProvider('schemaArrayProvider')] public function testFromArray($schema, $array) { - $this->object(Doc\Schema::fromArray($array))->isEqualTo($schema); + $this->assertEquals($schema, Doc\Schema::fromArray($array)); } } diff --git a/tests/functional/Glpi/Api/HL/Middleware/IPRestrictionRequestMiddleware.php b/phpunit/functional/Glpi/Api/HL/Middleware/IPRestrictionRequestMiddlewareTest.php similarity index 86% rename from tests/functional/Glpi/Api/HL/Middleware/IPRestrictionRequestMiddleware.php rename to phpunit/functional/Glpi/Api/HL/Middleware/IPRestrictionRequestMiddlewareTest.php index 9e285683fd9..e59ef6fab70 100644 --- a/tests/functional/Glpi/Api/HL/Middleware/IPRestrictionRequestMiddleware.php +++ b/phpunit/functional/Glpi/Api/HL/Middleware/IPRestrictionRequestMiddlewareTest.php @@ -35,9 +35,11 @@ namespace tests\units\Glpi\Api\HL\Middleware; -class IPRestrictionRequestMiddleware extends \GLPITestCase +use PHPUnit\Framework\Attributes\DataProvider; + +class IPRestrictionRequestMiddlewareTest extends \GLPITestCase { - protected function isIPAllowedProvider() + public static function isIPAllowedProvider() { return [ ['ip' => '127.0.0.1', 'allowed_ips' => '127.0.0.1', 'expected' => true], @@ -55,17 +57,14 @@ protected function isIPAllowedProvider() ]; } - /** - * @dataProvider isIPAllowedProvider - */ + #[DataProvider('isIPAllowedProvider')] public function testIsIPAllowed($ip, $allowed_ips, $expected) { $middleware = new \Glpi\Api\HL\Middleware\IPRestrictionRequestMiddleware(); - $this->variable($this->callPrivateMethod($middleware, 'isIPAllowed', $ip, $allowed_ips)) - ->isEqualTo($expected); + $this->assertEquals($expected, $this->callPrivateMethod($middleware, 'isIPAllowed', $ip, $allowed_ips)); } - protected function isCidrMatchProvider() + public static function isCidrMatchProvider() { return [ ['ip' => '10.10.13.5', 'range' => '10.10.13.0/24', 'expected' => true], @@ -78,13 +77,10 @@ protected function isCidrMatchProvider() ]; } - /** - * @dataProvider isCidrMatchProvider - */ + #[DataProvider('isCidrMatchProvider')] public function testIsCidrMatch($ip, $range, $expected) { $middleware = new \Glpi\Api\HL\Middleware\IPRestrictionRequestMiddleware(); - $this->variable($this->callPrivateMethod($middleware, 'isCidrMatch', $ip, $range)) - ->isEqualTo($expected); + $this->assertEquals($expected, $this->callPrivateMethod($middleware, 'isCidrMatch', $ip, $range)); } } diff --git a/tests/functional/Glpi/Api/HL/OpenAPIGenerator.php b/phpunit/functional/Glpi/Api/HL/OpenAPIGeneratorTest.php similarity index 90% rename from tests/functional/Glpi/Api/HL/OpenAPIGenerator.php rename to phpunit/functional/Glpi/Api/HL/OpenAPIGeneratorTest.php index e65ca5a98b6..75df4b5b0d3 100644 --- a/tests/functional/Glpi/Api/HL/OpenAPIGenerator.php +++ b/phpunit/functional/Glpi/Api/HL/OpenAPIGeneratorTest.php @@ -37,7 +37,7 @@ use HLAPITestCase; -class OpenAPIGenerator extends HLAPITestCase +class OpenAPIGeneratorTest extends HLAPITestCase { public function testExpandedEndpoints() { @@ -56,7 +56,7 @@ public function testExpandedEndpoints() $openapi = $generator->getSchema(); foreach ($to_check as $path) { - $this->array($openapi['paths'])->hasKey($path); + $this->assertArrayHasKey($path, $openapi['paths']); } // Check that the pre-expanded paths are not present @@ -66,7 +66,7 @@ public function testExpandedEndpoints() '/Assets/{itemtype}', ]; foreach ($to_check as $path) { - $this->array($openapi['paths'])->notHasKey($path); + $this->assertArrayNotHasKey($path, $openapi['paths']); } } @@ -91,7 +91,7 @@ public function testExpandedAttributesNoParameter() $openapi = $generator->getSchema(); foreach ($to_check as $endpoint) { - $this->array(array_filter($openapi['paths'][$endpoint['path']]['get']['parameters'], static fn ($v) => $v['name'] === $endpoint['placeholder']))->size->isEqualTo(0); + $this->assertEmpty(array_filter($openapi['paths'][$endpoint['path']]['get']['parameters'], static fn ($v) => $v['name'] === $endpoint['placeholder'])); } } } diff --git a/tests/functional/Glpi/Api/HL/RSQL/Lexer.php b/phpunit/functional/Glpi/Api/HL/RSQL/LexerTest.php similarity index 57% rename from tests/functional/Glpi/Api/HL/RSQL/Lexer.php rename to phpunit/functional/Glpi/Api/HL/RSQL/LexerTest.php index 3138e57f10d..6bfeaca43fa 100644 --- a/tests/functional/Glpi/Api/HL/RSQL/Lexer.php +++ b/phpunit/functional/Glpi/Api/HL/RSQL/LexerTest.php @@ -35,11 +35,14 @@ namespace tests\units\Glpi\Api\HL\RSQL; +use Glpi\Api\HL\RSQL\Lexer; +use Glpi\Api\HL\RSQL\RSQLException; use GLPITestCase; +use PHPUnit\Framework\Attributes\DataProvider; -class Lexer extends GLPITestCase +class LexerTest extends GLPITestCase { - protected function tokenizeProvider() + public static function tokenizeProvider() { return [ [ @@ -62,53 +65,56 @@ protected function tokenizeProvider() ]; } - /** - * @dataProvider tokenizeProvider - */ + #[DataProvider('tokenizeProvider')] public function testTokenize(string $query, array $expected) { - $tokens = \Glpi\Api\HL\RSQL\Lexer::tokenize($query); - $this->array($tokens)->isEqualTo($expected); + $tokens = Lexer::tokenize($query); + $this->assertEquals($expected, $tokens); } public function testMissingOperator() { - $this->exception(function () { - \Glpi\Api\HL\RSQL\Lexer::tokenize('id'); - })->isInstanceOf(\Glpi\Api\HL\RSQL\RSQLException::class) - ->hasMessage('RSQL query is missing an operator in filter for property "id"'); + $this->expectException(RSQLException::class); + $this->expectExceptionMessage('RSQL query is missing an operator in filter for property "id"'); + Lexer::tokenize('id'); } - public function testIncompleteOperator() + public static function incompleteOperatorProvider() { - $this->exception(function () { - \Glpi\Api\HL\RSQL\Lexer::tokenize('id='); - })->isInstanceOf(\Glpi\Api\HL\RSQL\RSQLException::class) - ->hasMessage('RSQL query has an incomplete operator in filter for property "id"'); - $this->exception(function () { - \Glpi\Api\HL\RSQL\Lexer::tokenize('id=l'); - })->isInstanceOf(\Glpi\Api\HL\RSQL\RSQLException::class) - ->hasMessage('RSQL query has an incomplete operator in filter for property "id"'); + return [ + ['id='], + ['id=l'] + ]; + } + + #[DataProvider('incompleteOperatorProvider')] + public function testIncompleteOperator(string $query) + { + $this->expectException(RSQLException::class); + $this->expectExceptionMessage('RSQL query has an incomplete operator in filter for property "id"'); + Lexer::tokenize($query); } public function testMissingValue() { - $this->exception(function () { - \Glpi\Api\HL\RSQL\Lexer::tokenize('id=like='); - })->isInstanceOf(\Glpi\Api\HL\RSQL\RSQLException::class) - ->hasMessage('RSQL query is missing a value in filter for property "id"'); + $this->expectException(RSQLException::class); + $this->expectExceptionMessage('RSQL query is missing a value in filter for property "id"'); + Lexer::tokenize('id=like='); } - public function testUnclosedGroup() + public static function unclosedGroupProvider() { - $this->exception(function () { - \Glpi\Api\HL\RSQL\Lexer::tokenize('(id=like=1'); - })->isInstanceOf(\Glpi\Api\HL\RSQL\RSQLException::class) - ->hasMessage('RSQL query has one or more unclosed groups'); + return [ + ['(id=like=1'], + ['name==Test1,((id=like=1),(name==Test2)'] + ]; + } - $this->exception(function () { - \Glpi\Api\HL\RSQL\Lexer::tokenize('name==Test1,((id=like=1),(name==Test2)'); - })->isInstanceOf(\Glpi\Api\HL\RSQL\RSQLException::class) - ->hasMessage('RSQL query has one or more unclosed groups'); + #[DataProvider('unclosedGroupProvider')] + public function testUnclosedGroup(string $query) + { + $this->expectException(RSQLException::class); + $this->expectExceptionMessage('RSQL query has one or more unclosed groups'); + Lexer::tokenize($query); } } diff --git a/tests/functional/Glpi/Api/HL/RSQL/Parser.php b/phpunit/functional/Glpi/Api/HL/RSQL/ParserTest.php similarity index 85% rename from tests/functional/Glpi/Api/HL/RSQL/Parser.php rename to phpunit/functional/Glpi/Api/HL/RSQL/ParserTest.php index 01208effe2d..df19ea47b8a 100644 --- a/tests/functional/Glpi/Api/HL/RSQL/Parser.php +++ b/phpunit/functional/Glpi/Api/HL/RSQL/ParserTest.php @@ -36,12 +36,15 @@ namespace tests\units\Glpi\Api\HL\RSQL; use Glpi\Api\HL\Doc\Schema; +use Glpi\Api\HL\RSQL\Error; +use Glpi\Api\HL\RSQL\Parser; use Glpi\Api\HL\Search; use GLPITestCase; +use PHPUnit\Framework\Attributes\DataProvider; -class Parser extends GLPITestCase +class ParserTest extends GLPITestCase { - protected function parseProvider() + public static function parseProvider() { return [ [ @@ -84,9 +87,7 @@ protected function parseProvider() ]; } - /** - * @dataProvider parseProvider - */ + #[DataProvider('parseProvider')] public function testParse(array $tokens, string $expected) { $schema = [ @@ -129,8 +130,8 @@ public function testParse(array $tokens, string $expected) $search_class->getProperty('schema')->setValue($search, $schema); $search_class->getProperty('flattened_properties')->setValue($search, Schema::flattenProperties($schema['properties'])); $search_class->getProperty('joins')->setValue($search, Schema::getJoins($schema['properties'])); - $parser = new \Glpi\Api\HL\RSQL\Parser($search); - $this->string((string)$parser->parse($tokens)->getSQLCriteria())->isEqualTo($expected); + $parser = new Parser($search); + $this->assertEquals($expected, (string)$parser->parse($tokens)->getSQLCriteria()); } /** @@ -156,24 +157,24 @@ public function testIgnoreInvalidProperties() $search_class->getProperty('schema')->setValue($search, $schema); $search_class->getProperty('flattened_properties')->setValue($search, Schema::flattenProperties($schema['properties'])); $search_class->getProperty('joins')->setValue($search, Schema::getJoins($schema['properties'])); - $parser = new \Glpi\Api\HL\RSQL\Parser($search); + $parser = new Parser($search); $result = $parser->parse([[5, 'test'], [6, '=='], [7, 'test']]); - $this->string((string)$result->getSQLCriteria())->isEqualTo('1'); - $this->variable($result->getInvalidFilters()['test'])->isIdenticalTo(\Glpi\Api\HL\RSQL\Error::UNKNOWN_PROPERTY); + $this->assertEquals('1', (string)$result->getSQLCriteria()); + $this->assertEquals(Error::UNKNOWN_PROPERTY, $result->getInvalidFilters()['test']); // Test an invalid filter with a valid one $result = $parser->parse([[5, 'test'], [6, '=='], [7, 'test'], [1, ';'], [5, 'name'], [6, '=='], [7, 'test']]); - $this->string((string)$result->getSQLCriteria())->isEqualTo("(`_`.`name` = 'test')"); - $this->variable($result->getInvalidFilters()['test'])->isIdenticalTo(\Glpi\Api\HL\RSQL\Error::UNKNOWN_PROPERTY); + $this->assertEquals("(`_`.`name` = 'test')", (string)$result->getSQLCriteria()); + $this->assertEquals(Error::UNKNOWN_PROPERTY, $result->getInvalidFilters()['test']); // Test invalid operator $result = $parser->parse([[5, 'name'], [6, '=f='], [7, 'test']]); - $this->string((string)$result->getSQLCriteria())->isEqualTo('1'); - $this->variable($result->getInvalidFilters()['name'])->isIdenticalTo(\Glpi\Api\HL\RSQL\Error::UNKNOWN_OPERATOR); + $this->assertEquals('1', (string)$result->getSQLCriteria()); + $this->assertEquals(Error::UNKNOWN_OPERATOR, $result->getInvalidFilters()['name']); // Mapped properties should be ignored $result = $parser->parse([[5, 'mapped'], [6, '=='], [7, 'test']]); - $this->string((string)$result->getSQLCriteria())->isEqualTo('1'); - $this->variable($result->getInvalidFilters()['mapped'])->isIdenticalTo(\Glpi\Api\HL\RSQL\Error::MAPPED_PROPERTY); + $this->assertEquals('1', (string)$result->getSQLCriteria()); + $this->assertEquals(Error::MAPPED_PROPERTY, $result->getInvalidFilters()['mapped']); } } diff --git a/tests/functional/Glpi/Api/HL/Router.php b/phpunit/functional/Glpi/Api/HL/RouterTest.php similarity index 83% rename from tests/functional/Glpi/Api/HL/Router.php rename to phpunit/functional/Glpi/Api/HL/RouterTest.php index 1d67e522a5e..c8a50e9f020 100644 --- a/tests/functional/Glpi/Api/HL/Router.php +++ b/phpunit/functional/Glpi/Api/HL/RouterTest.php @@ -36,6 +36,7 @@ namespace tests\units\Glpi\Api\HL; use Glpi\Api\HL\Route; +use Glpi\Api\HL\Router; use Glpi\Api\HL\RouteVersion; use Glpi\Http\JSONResponse; use Glpi\Http\Request; @@ -43,17 +44,17 @@ use GLPITestCase; use Psr\Http\Message\RequestInterface; -class Router extends GLPITestCase +class RouterTest extends GLPITestCase { public function testMatch() { $router = TestRouter::getInstance(); - $this->variable($router->match(new Request('GET', '/test')))->isNotNull(); + $this->assertNotNull($router->match(new Request('GET', '/test'))); } public function testAllRoutesHaveVersioningInfo() { - $router = \Glpi\Api\HL\Router::getInstance(); + $router = Router::getInstance(); $all_routes = $router->getAllRoutes(); $routes_missing_versions = []; @@ -63,12 +64,12 @@ public function testAllRoutesHaveVersioningInfo() $routes_missing_versions[] = $route->getRoutePath(); } } - $this->array($routes_missing_versions)->isEmpty('Routes missing versioning info: ' . implode(', ', $routes_missing_versions)); + $this->assertEmpty($routes_missing_versions, 'Routes missing versioning info: ' . implode(', ', $routes_missing_versions)); } public function testAllSchemasHaveVersioningInfo() { - $router = \Glpi\Api\HL\Router::getInstance(); + $router = Router::getInstance(); $controllers = $router->getControllers(); $schemas_missing_versions = []; @@ -84,23 +85,23 @@ public function testAllSchemasHaveVersioningInfo() } } - $this->array($schemas_missing_versions)->isEmpty('Schemas missing versioning info: ' . implode(', ', $schemas_missing_versions)); + $this->assertEmpty($schemas_missing_versions, 'Schemas missing versioning info: ' . implode(', ', $schemas_missing_versions)); } public function testNormalizeAPIVersion() { - $this->string(TestRouter::normalizeAPIVersion('50'))->isEqualTo('50.2.0'); - $this->string(TestRouter::normalizeAPIVersion('50.1.1'))->isEqualTo('50.1.1'); - $this->string(TestRouter::normalizeAPIVersion('50.1'))->isEqualTo('50.1.2'); - $this->string(TestRouter::normalizeAPIVersion('50.2'))->isEqualTo('50.2.0'); + $this->assertEquals('50.2.0', TestRouter::normalizeAPIVersion('50')); + $this->assertEquals('50.1.1', TestRouter::normalizeAPIVersion('50.1.1')); + $this->assertEquals('50.1.2', TestRouter::normalizeAPIVersion('50.1')); + $this->assertEquals('50.2.0', TestRouter::normalizeAPIVersion('50.2')); } } // @codingStandardsIgnoreStart -class TestRouter extends \Glpi\Api\HL\Router +class TestRouter extends Router { // @codingStandardsIgnoreEnd - public static function getInstance(): \Glpi\Api\HL\Router + public static function getInstance(): Router { static $router = null; if ($router === null) { diff --git a/src/Glpi/Api/HL/Router.php b/src/Glpi/Api/HL/Router.php index 87e4e33b104..99842bdb194 100644 --- a/src/Glpi/Api/HL/Router.php +++ b/src/Glpi/Api/HL/Router.php @@ -577,6 +577,7 @@ private function doResponseMiddleware(MiddlewareInput $input): void public function handleRequest(Request $request): Response { // Start an output buffer to capture any potential debug errors + $current_output_buffer_level = ob_get_level(); ob_start(); $response = null; $original_method = $request->getMethod(); @@ -686,15 +687,11 @@ public function handleRequest(Request $request): Response if ($original_method === 'HEAD') { $response = $response->withBody(Utils::streamFor('')); } - // Clear output buffers - $ob_config = ini_get('output_buffering'); - $max_level = filter_var($ob_config, FILTER_VALIDATE_BOOLEAN) ? 1 : 0; - while (ob_get_level() > $max_level) { + // Clear output buffers up to the level when the request was started + while (ob_get_level() > $current_output_buffer_level) { ob_end_clean(); } - if (ob_get_level() > 0) { - ob_clean(); - } + return $response; } diff --git a/src/Toolbox.php b/src/Toolbox.php index 03ea5c0fe6c..096a31a8161 100644 --- a/src/Toolbox.php +++ b/src/Toolbox.php @@ -592,19 +592,22 @@ public static function sendFile($file, $filename, $mime = null, $expires_headers $etag = md5_file($file); $lastModified = filemtime($file); - // Make sure there is nothing in the output buffer (In case stuff was added by core or misbehaving plugin). - // If there is any extra data, the sent file will be corrupted. - // 1. Turn off any extra buffering level. Keep one buffering level if PHP output_buffering directive is not "off". - $ob_config = ini_get('output_buffering'); - $max_buffering_level = $ob_config !== false && (strtolower($ob_config) === 'on' || (is_numeric($ob_config) && (int)$ob_config > 0)) - ? 1 - : 0; - while (ob_get_level() > $max_buffering_level) { - ob_end_clean(); - } - // 2. Clean any buffered output in remaining level (output_buffering="on" case). - if (ob_get_level() > 0) { - ob_clean(); + // No need to clear the output buffer if we are returning a Response object. + if (!$return_response) { + // Make sure there is nothing in the output buffer (In case stuff was added by core or misbehaving plugin). + // If there is any extra data, the sent file will be corrupted. + // 1. Turn off any extra buffering level. Keep one buffering level if PHP output_buffering directive is not "off". + $ob_config = ini_get('output_buffering'); + $max_buffering_level = $ob_config !== false && (strtolower($ob_config) === 'on' || (is_numeric($ob_config) && (int)$ob_config > 0)) + ? 1 + : 0; + while (ob_get_level() > $max_buffering_level) { + ob_end_clean(); + } + // 2. Clean any buffered output in remaining level (output_buffering="on" case). + if (ob_get_level() > 0) { + ob_clean(); + } } $headers = [