1<?php 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18use GuzzleHttp\ClientInterface; 19use Symfony\Component\DomCrawler\Crawler; 20use League\Flysystem\Adapter\Local; 21use League\Flysystem\Filesystem; 22use Cache\Adapter\Filesystem\FilesystemCachePool; 23use PHPUnit\Framework\TestCase; 24 25class BaseTest extends TestCase 26{ 27 private $key; 28 private $client; 29 protected $testDir = __DIR__; 30 31 public function getClient() 32 { 33 if (!$this->client) { 34 $this->client = $this->createClient(); 35 } 36 37 return $this->client; 38 } 39 40 public function getCache($path = null) 41 { 42 $path = $path ?: sys_get_temp_dir().'/google-api-php-client-tests/'; 43 $filesystemAdapter = new Local($path); 44 $filesystem = new Filesystem($filesystemAdapter); 45 46 return new FilesystemCachePool($filesystem); 47 } 48 49 private function createClient() 50 { 51 $options = [ 52 'auth' => 'google_auth', 53 'exceptions' => false, 54 ]; 55 56 if ($proxy = getenv('HTTP_PROXY')) { 57 $options['proxy'] = $proxy; 58 $options['verify'] = false; 59 } 60 61 // adjust constructor depending on guzzle version 62 if (!$this->isGuzzle6()) { 63 $options = ['defaults' => $options]; 64 } 65 66 $httpClient = new GuzzleHttp\Client($options); 67 68 $client = new Google_Client(); 69 $client->setApplicationName('google-api-php-client-tests'); 70 $client->setHttpClient($httpClient); 71 $client->setScopes([ 72 "https://www.googleapis.com/auth/plus.me", 73 "https://www.googleapis.com/auth/urlshortener", 74 "https://www.googleapis.com/auth/tasks", 75 "https://www.googleapis.com/auth/adsense", 76 "https://www.googleapis.com/auth/youtube", 77 "https://www.googleapis.com/auth/drive", 78 ]); 79 80 if ($this->key) { 81 $client->setDeveloperKey($this->key); 82 } 83 84 list($clientId, $clientSecret) = $this->getClientIdAndSecret(); 85 $client->setClientId($clientId); 86 $client->setClientSecret($clientSecret); 87 if (version_compare(PHP_VERSION, '5.5', '>=')) { 88 $client->setCache($this->getCache()); 89 } 90 91 return $client; 92 } 93 94 public function checkToken() 95 { 96 $client = $this->getClient(); 97 $cache = $client->getCache(); 98 $cacheItem = $cache->getItem('access_token'); 99 100 if (!$token = $cacheItem->get()) { 101 if (!$token = $this->tryToGetAnAccessToken($client)) { 102 return $this->markTestSkipped("Test requires access token"); 103 } 104 $cacheItem->set($token); 105 $cache->save($cacheItem); 106 } 107 108 $client->setAccessToken($token); 109 110 if ($client->isAccessTokenExpired()) { 111 // as long as we have client credentials, even if its expired 112 // our access token will automatically be refreshed 113 $this->checkClientCredentials(); 114 } 115 116 return true; 117 } 118 119 public function tryToGetAnAccessToken(Google_Client $client) 120 { 121 $this->checkClientCredentials(); 122 123 $client->setRedirectUri("urn:ietf:wg:oauth:2.0:oob"); 124 $client->setConfig('access_type', 'offline'); 125 $authUrl = $client->createAuthUrl(); 126 127 echo "\nPlease enter the auth code:\n"; 128 ob_flush(); 129 `open '$authUrl'`; 130 $authCode = trim(fgets(STDIN)); 131 132 if ($accessToken = $client->fetchAccessTokenWithAuthCode($authCode)) { 133 if (isset($accessToken['access_token'])) { 134 return $accessToken; 135 } 136 } 137 138 return false; 139 } 140 141 private function getClientIdAndSecret() 142 { 143 $clientId = getenv('GCLOUD_CLIENT_ID') ?: null; 144 $clientSecret = getenv('GCLOUD_CLIENT_SECRET') ?: null; 145 146 return array($clientId, $clientSecret); 147 } 148 149 public function checkClientCredentials() 150 { 151 list($clientId, $clientSecret) = $this->getClientIdAndSecret(); 152 if (!($clientId && $clientSecret)) { 153 $this->markTestSkipped("Test requires GCLOUD_CLIENT_ID and GCLOUD_CLIENT_SECRET to be set"); 154 } 155 } 156 157 public function checkServiceAccountCredentials() 158 { 159 if (!$f = getenv('GOOGLE_APPLICATION_CREDENTIALS')) { 160 $skip = "This test requires the GOOGLE_APPLICATION_CREDENTIALS environment variable to be set\n" 161 . "see https://developers.google.com/accounts/docs/application-default-credentials"; 162 $this->markTestSkipped($skip); 163 164 return false; 165 } 166 167 if (!file_exists($f)) { 168 $this->markTestSkipped('invalid path for GOOGLE_APPLICATION_CREDENTIALS'); 169 } 170 171 return true; 172 } 173 174 public function checkKey() 175 { 176 $this->key = $this->loadKey(); 177 178 if (!strlen($this->key)) { 179 $this->markTestSkipped("Test requires api key\nYou can create one in your developer console"); 180 return false; 181 } 182 } 183 184 public function loadKey() 185 { 186 if (file_exists($f = __DIR__ . DIRECTORY_SEPARATOR . '.apiKey')) { 187 return file_get_contents($f); 188 } 189 } 190 191 protected function loadExample($example) 192 { 193 // trick app into thinking we are a web server 194 $_SERVER['HTTP_USER_AGENT'] = 'google-api-php-client-tests'; 195 $_SERVER['HTTP_HOST'] = 'localhost'; 196 $_SERVER['REQUEST_METHOD'] = 'GET'; 197 198 // include the file and return an HTML crawler 199 $file = __DIR__ . '/../examples/' . $example; 200 if (is_file($file)) { 201 ob_start(); 202 include $file; 203 $html = ob_get_clean(); 204 205 return new Crawler($html); 206 } 207 208 return false; 209 } 210 211 protected function isGuzzle6() 212 { 213 $version = ClientInterface::VERSION; 214 215 return ('6' === $version[0]); 216 } 217 218 protected function isGuzzle5() 219 { 220 $version = ClientInterface::VERSION; 221 222 return ('5' === $version[0]); 223 } 224 225 public function onlyGuzzle6() 226 { 227 if (!$this->isGuzzle6()) { 228 $this->markTestSkipped('Guzzle 6 only'); 229 } 230 } 231 232 public function onlyPhp55AndAbove() 233 { 234 if (version_compare(PHP_VERSION, '5.5', '<')) { 235 $this->markTestSkipped('PHP 5.5 and above only'); 236 } 237 } 238 239 public function onlyGuzzle5() 240 { 241 if (!$this->isGuzzle5()) { 242 $this->markTestSkipped('Guzzle 5 only'); 243 } 244 } 245} 246