Complex classes like TestingTrait often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use TestingTrait, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 22 | trait TestingTrait |
||
| 23 | { |
||
| 24 | |||
| 25 | /** |
||
| 26 | * the Logged in user, used for protected routes. |
||
| 27 | * |
||
| 28 | * @var User |
||
| 29 | */ |
||
| 30 | public $loggedInTestingUser; |
||
| 31 | |||
| 32 | /** |
||
| 33 | * @param $endpoint |
||
| 34 | * @param string $verb |
||
| 35 | * @param array $data |
||
| 36 | * @param bool|true $protected |
||
| 37 | * @param array $header |
||
| 38 | * |
||
| 39 | * @throws \Symfony\Component\Debug\Exception\UndefinedMethodException |
||
| 40 | * |
||
| 41 | * @return mixed |
||
| 42 | */ |
||
| 43 | public function apiCall($endpoint, $verb = 'get', array $data = [], $protected = true, array $header = []) |
||
| 44 | { |
||
| 45 | $content = json_encode($data); |
||
| 46 | |||
| 47 | $headers = array_merge([ |
||
| 48 | 'CONTENT_LENGTH' => mb_strlen($content, '8bit'), |
||
| 49 | // 'CONTENT_TYPE' => 'application/json', |
||
|
|
|||
| 50 | 'Accept' => 'application/json', |
||
| 51 | ], $header); |
||
| 52 | |||
| 53 | // if endpoint is protected (requires token to access it's functionality) |
||
| 54 | if ($protected && !array_has($header, 'Authorization')) { |
||
| 55 | // append the token to the header |
||
| 56 | $headers['Authorization'] = 'Bearer ' . $this->getLoggedInTestingUserToken(); |
||
| 57 | } |
||
| 58 | |||
| 59 | if (!$protected && !array_has($header, 'Visitor-Id')) { |
||
| 60 | // append the Device ID to the header (IPhone UUID, Android ID, ...) |
||
| 61 | $headers['Visitor-Id'] = str_random(40); |
||
| 62 | } |
||
| 63 | |||
| 64 | $verb = strtolower($verb); |
||
| 65 | |||
| 66 | switch ($verb) { |
||
| 67 | case 'get': |
||
| 68 | $endpoint = $data ? $endpoint . '?' . http_build_query($data) : $endpoint; |
||
| 69 | $response = $this->get($endpoint, $headers)->response; |
||
| 70 | break; |
||
| 71 | case 'post': |
||
| 72 | case 'put': |
||
| 73 | case 'patch': |
||
| 74 | case 'delete': |
||
| 75 | $response = $this->{$verb}($endpoint, $data, $headers)->response; |
||
| 76 | break; |
||
| 77 | default: |
||
| 78 | throw new UndefinedMethodException('Undefined HTTP Verb (' . $verb . ').'); |
||
| 79 | } |
||
| 80 | |||
| 81 | return $response; |
||
| 82 | } |
||
| 83 | |||
| 84 | /** |
||
| 85 | * @param \Dingo\Api\Http\Response $response |
||
| 86 | * @param array $messages |
||
| 87 | */ |
||
| 88 | public function assertValidationErrorContain(DingoAPIResponse $response, array $messages) |
||
| 97 | |||
| 98 | /** |
||
| 99 | * get teh current logged in user. |
||
| 100 | * |
||
| 101 | * @return \App\Port\Tests\PHPUnit\Traits\User|mixed |
||
| 102 | */ |
||
| 103 | public function getLoggedInTestingUser() |
||
| 113 | |||
| 114 | /** |
||
| 115 | * @return \App\Port\Tests\PHPUnit\Traits\User|mixed |
||
| 116 | */ |
||
| 117 | public function getLoggedInTestingAdmin() |
||
| 125 | |||
| 126 | /** |
||
| 127 | * @param $user |
||
| 128 | * |
||
| 129 | * @return mixed |
||
| 130 | */ |
||
| 131 | public function makeAdmin($user) |
||
| 139 | |||
| 140 | /** |
||
| 141 | * get teh current logged in user token. |
||
| 142 | * |
||
| 143 | * @return string |
||
| 144 | */ |
||
| 145 | public function getLoggedInTestingUserToken() |
||
| 149 | |||
| 150 | /** |
||
| 151 | * @param null $userDetails |
||
| 152 | * |
||
| 153 | * @return mixed |
||
| 154 | */ |
||
| 155 | public function registerAndLoginTestingUser($userDetails = null) |
||
| 178 | |||
| 179 | /** |
||
| 180 | * @param null $userDetails |
||
| 181 | * |
||
| 182 | * @return mixed |
||
| 183 | */ |
||
| 184 | public function registerAndLoginTestingAdmin($userDetails = null) |
||
| 192 | |||
| 193 | /** |
||
| 194 | * @param $keys |
||
| 195 | * @param $response |
||
| 196 | */ |
||
| 197 | public function assertResponseContainKeys($keys, $response) |
||
| 207 | |||
| 208 | /** |
||
| 209 | * @param $values |
||
| 210 | * @param $response |
||
| 211 | */ |
||
| 212 | public function assertResponseContainValues($values, $response) |
||
| 222 | |||
| 223 | /** |
||
| 224 | * @param $data |
||
| 225 | * @param $response |
||
| 226 | */ |
||
| 227 | public function assertResponseContainKeyValue($data, $response) |
||
| 239 | |||
| 240 | /** |
||
| 241 | * Prettify printing JSON data (mainly for API responses) in the terminal. |
||
| 242 | * |
||
| 243 | * @param $json |
||
| 244 | * |
||
| 245 | * @return string |
||
| 246 | */ |
||
| 247 | public function ddj($json) |
||
| 299 | |||
| 300 | /** |
||
| 301 | * Migrate the database. |
||
| 302 | */ |
||
| 303 | public function migrateDatabase() |
||
| 307 | |||
| 308 | /** |
||
| 309 | * @param $response |
||
| 310 | * |
||
| 311 | * @return mixed |
||
| 312 | */ |
||
| 313 | private function responseToArray($response) |
||
| 325 | |||
| 326 | /** |
||
| 327 | * Format the given key and value into a JSON string for expectation checks. |
||
| 328 | * |
||
| 329 | * @param string $key |
||
| 330 | * @param mixed $value |
||
| 331 | * |
||
| 332 | * @return string |
||
| 333 | */ |
||
| 334 | private function formatToKeyValueToString($key, $value) |
||
| 348 | |||
| 349 | /** |
||
| 350 | * Mocking helper |
||
| 351 | * |
||
| 352 | * @param $class |
||
| 353 | * |
||
| 354 | * @return \Mockery\MockInterface |
||
| 355 | */ |
||
| 356 | public function mock($class) |
||
| 363 | |||
| 364 | /** |
||
| 365 | * get response object, get the string content from it and convert it to an std object |
||
| 366 | * making it easier to read |
||
| 367 | * |
||
| 368 | * @param $response |
||
| 369 | * |
||
| 370 | * @return mixed |
||
| 371 | */ |
||
| 372 | public function getResponseObject(Response $response) |
||
| 376 | |||
| 377 | /** |
||
| 378 | * Inject the ID in the Endpoint URI |
||
| 379 | * |
||
| 380 | * Example: you give it ('users/{id}/stores', 100) it returns 'users/100/stores' |
||
| 381 | * |
||
| 382 | * @param $endpoint |
||
| 383 | * @param $id |
||
| 384 | * |
||
| 385 | * @return mixed |
||
| 386 | */ |
||
| 387 | public function injectEndpointId($endpoint, $id) |
||
| 391 | |||
| 392 | } |
||
| 393 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.