Source of file RESTfulAPITest.php
Size: 8,106 Bytes - Last Modified: 2021-12-24T06:41:16+00:00
/var/www/docs.ssmods.com/process/src/tests/API/RESTfulAPITest.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 | <?php namespace Colymba\RESTfulAPI\Tests\API; use Colymba\RESTfulAPI\RESTfulAPI; use Colymba\RESTfulAPI\Tests\RESTfulAPITester; use SilverStripe\Control\Director; use SilverStripe\Core\Config\Config; use Colymba\RESTfulAPI\Tests\Fixtures\ApiTestAuthor; use Colymba\RESTfulAPI\Tests\Fixtures\ApiTestBook; use Colymba\RESTfulAPI\Tests\Fixtures\ApiTestLibrary; /** * RESTfulAPI Test suite * * @author Thierry Francois @colymba thierry@colymba.com * @copyright Copyright (c) 2013, Thierry Francois * * @license http://opensource.org/licenses/BSD-3-Clause BSD Simplified * * @package RESTfulAPI * @subpackage Tests */ class RESTfulAPITest extends RESTfulAPITester { protected static $extra_dataobjects = array( ApiTestAuthor::class, ApiTestBook::class, ApiTestLibrary::class, ); /* ********************************************************** * TESTS * */ /** * Checks that api access config check works */ public function testDataObjectAPIEnaled() { Config::inst()->update(RESTfulAPI::class, 'access_control_policy', 'ACL_CHECK_CONFIG_ONLY'); // ---------------- // Method Calls // Disabled by default $enabled = RESTfulAPI::api_access_control(ApiTestAuthor::class); $this->assertFalse($enabled, 'Access control should return FALSE by default'); // Enabled Config::inst()->update(ApiTestAuthor::class, 'api_access', true); $enabled = RESTfulAPI::api_access_control(ApiTestAuthor::class); $this->assertTrue($enabled, 'Access control should return TRUE when api_access is enbaled'); // Method specific Config::inst()->update(ApiTestAuthor::class, 'api_access', 'GET,POST'); $enabled = RESTfulAPI::api_access_control(ApiTestAuthor::class); $this->assertTrue($enabled, 'Access control should return TRUE when api_access is enbaled with default GET method'); $enabled = RESTfulAPI::api_access_control(ApiTestAuthor::class, 'POST'); $this->assertTrue($enabled, 'Access control should return TRUE when api_access match HTTP method'); $enabled = RESTfulAPI::api_access_control(ApiTestAuthor::class, 'PUT'); $this->assertFalse($enabled, 'Access control should return FALSE when api_access does not match method'); // ---------------- // API Calls /* // Access authorised $response = Director::test('api/ApiTestAuthor/1', null, null, 'GET'); $this->assertEquals( $response->getStatusCode(), 200 ); // Access denied Config::inst()->update(ApiTestAuthor::class, 'api_access', false); $response = Director::test('api/ApiTestAuthor/1', null, null, 'GET'); $this->assertEquals( $response->getStatusCode(), 403 ); // Access denied Config::inst()->update(ApiTestAuthor::class, 'api_access', 'POST'); $response = Director::test('api/ApiTestAuthor/1', null, null, 'GET'); $this->assertEquals( $response->getStatusCode(), 403 ); */ } /* ********************************************************************** * CORS * */ /** * Check that CORS headers aren't set * when disabled via config * * @group CORSPreflight */ public function testCORSDisabled() { Config::inst()->update(RESTfulAPI::class, 'cors', array( 'Enabled' => false, )); $requestHeaders = $this->getOPTIONSHeaders(); $response = Director::test('api/ApiTestBook/1', null, null, 'OPTIONS', null, $requestHeaders); $headers = $response->getHeaders(); $this->assertFalse(array_key_exists('Access-Control-Allow-Origin', $headers), 'CORS ORIGIN header should not be present'); $this->assertFalse(array_key_exists('Access-Control-Allow-Headers', $headers), 'CORS HEADER header should not be present'); $this->assertFalse(array_key_exists('Access-Control-Allow-Methods', $headers), 'CORS METHOD header should not be present'); $this->assertFalse(array_key_exists('Access-Control-Max-Age', $headers), 'CORS AGE header should not be present'); } /** * Checks default allow all CORS settings * * @group CORSPreflight */ public function testCORSAllowAll() { $corsConfig = Config::inst()->get(RESTfulAPI::class, 'cors'); $requestHeaders = $this->getOPTIONSHeaders('GET', 'http://google.com'); $response = Director::test('api/ApiTestBook/1', null, null, 'OPTIONS', null, $requestHeaders); $responseHeaders = $response->getHeaders(); $this->assertEquals( $requestHeaders['Origin'], $responseHeaders['Access-Control-Allow-Origin'], 'CORS headers should have same ORIGIN' ); $this->assertEquals( $corsConfig['Allow-Methods'], $responseHeaders['Access-Control-Allow-Methods'], 'CORS headers should have same METHOD' ); $this->assertEquals( $requestHeaders['Access-Control-Request-Headers'], $responseHeaders['Access-Control-Allow-Headers'], 'CORS headers should have same ALLOWED HEADERS' ); $this->assertEquals( $corsConfig['Max-Age'], $responseHeaders['Access-Control-Max-Age'], 'CORS headers should have same MAX AGE' ); } /** * Checks CORS only allow HTTP methods specify in config */ public function testCORSHTTPMethodFiltering() { Config::inst()->update(RESTfulAPI::class, 'cors', array( 'Enabled' => true, 'Allow-Origin' => '*', 'Allow-Headers' => '*', 'Allow-Methods' => 'GET', 'Max-Age' => 86400, )); // Seding GET request, GET should be allowed $requestHeaders = $this->getRequestHeaders(); $response = Director::test('api/ApiTestBook/1', null, null, 'GET', null, $requestHeaders); $responseHeaders = $response->getHeaders(); $this->assertEquals( 'GET', $responseHeaders['access-control-allow-methods'], 'Only HTTP GET method should be allowed in access-control-allow-methods HEADER' ); // Seding POST request, only GET should be allowed $response = Director::test('api/ApiTestBook/1', null, null, 'POST', null, $requestHeaders); $responseHeaders = $response->getHeaders(); $this->assertEquals( 'GET', $responseHeaders['access-control-allow-methods'], 'Only HTTP GET method should be allowed in access-control-allow-methods HEADER' ); } /* ********************************************************************** * API REQUESTS * */ public function testFullBasicAPIRequest() { Config::inst()->update(RESTfulAPI::class, 'authentication_policy', false); Config::inst()->update(RESTfulAPI::class, 'access_control_policy', 'ACL_CHECK_CONFIG_ONLY'); Config::inst()->update(ApiTestAuthor::class, 'api_access', true); // Default serializer Config::inst()->update(RESTfulAPI::class, 'dependencies', array( 'authenticator' => null, 'authority' => null, 'queryHandler' => '%$Colymba\RESTfulAPI\QueryHandlers\DefaultQueryHandler', 'serializer' => '%$Colymba\RESTfulAPI\Serializers\DefaultSerializer', )); Config::inst()->update(RESTfulAPI::class, 'dependencies', array( 'deSerializer' => '%$Colymba\RESTfulAPI\Serializers\DefaultDeSerializer', )); $response = Director::test('api/apitestauthor/1', null, null, 'GET'); $this->assertEquals( 200, $response->getStatusCode(), "API request for existing record should resolve" ); $json = json_decode($response->getBody()); $this->assertEquals( JSON_ERROR_NONE, json_last_error(), "API request should return valid JSON" ); } } |