Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php  | 
            ||
| 12 | class IpAddressTest extends NimoTestCase  | 
            ||
| 13 | { | 
            ||
| 14 | 1 | public function testIpSetByRemoteAddr()  | 
            |
| 15 |     { | 
            ||
| 16 | 1 | $middleware = new IpAddress();  | 
            |
| 17 | |||
| 18 | 1 | $request = ServerRequestFactory::fromGlobals([  | 
            |
| 19 | 1 | 'REMOTE_ADDR' => '192.168.1.1',  | 
            |
| 20 | ]);  | 
            ||
| 21 | 1 | $this->runRequest($middleware, $request);  | 
            |
| 22 | |||
| 23 | 1 |         Assert::assertSame('192.168.1.1', $middleware->getIpAddress()); | 
            |
| 24 | 1 | }  | 
            |
| 25 | |||
| 26 | 1 | public function testIpIsNullIfMissing()  | 
            |
| 27 |     { | 
            ||
| 28 | 1 | $middleware = new IpAddress();  | 
            |
| 29 | |||
| 30 | 1 | $request = ServerRequestFactory::fromGlobals();  | 
            |
| 31 | 1 | $this->runRequest($middleware, $request);  | 
            |
| 32 | |||
| 33 | |||
| 34 | 1 | Assert::assertNull($middleware->getIpAddress());  | 
            |
| 35 | 1 | }  | 
            |
| 36 | |||
| 37 | 1 | public function testXForwardedForIp()  | 
            |
| 38 |     { | 
            ||
| 39 | 1 | $middleware = new IpAddress(['192.168.1.1']);  | 
            |
| 40 | |||
| 41 | 1 | $request = ServerRequestFactory::fromGlobals([  | 
            |
| 42 | 1 | 'REMOTE_ADDR' => '192.168.1.1',  | 
            |
| 43 | 'HTTP_X_FORWARDED_FOR' => '192.168.1.3, 192.168.1.2, 192.168.1.1'  | 
            ||
| 44 | ]);  | 
            ||
| 45 | 1 | $this->runRequest($middleware, $request);  | 
            |
| 46 | |||
| 47 | 1 |         Assert::assertSame('192.168.1.3', $middleware->getIpAddress()); | 
            |
| 48 | 1 | }  | 
            |
| 49 | |||
| 50 | 1 | public function testProxyIpIsIgnored()  | 
            |
| 51 |     { | 
            ||
| 52 | 1 | $middleware = new IpAddress();  | 
            |
| 53 | |||
| 54 | 1 | $request = ServerRequestFactory::fromGlobals([  | 
            |
| 55 | 1 | 'REMOTE_ADDR' => '192.168.0.1',  | 
            |
| 56 | 'HTTP_X_FORWARDED_FOR' => '192.168.1.3, 192.168.1.2, 192.168.1.1'  | 
            ||
| 57 | ]);  | 
            ||
| 58 | 1 | $this->runRequest($middleware, $request);  | 
            |
| 59 | |||
| 60 | 1 |         Assert::assertSame('192.168.0.1', $middleware->getIpAddress()); | 
            |
| 61 | 1 | }  | 
            |
| 62 | |||
| 63 | 1 | public function testHttpClientIp()  | 
            |
| 64 |     { | 
            ||
| 65 | 1 | $middleware = new IpAddress(['192.168.1.1']);  | 
            |
| 66 | |||
| 67 | 1 | $request = ServerRequestFactory::fromGlobals([  | 
            |
| 68 | 1 | 'REMOTE_ADDR' => '192.168.1.1',  | 
            |
| 69 | 'HTTP_CLIENT_IP' => '192.168.1.3'  | 
            ||
| 70 | ]);  | 
            ||
| 71 | 1 | $this->runRequest($middleware, $request);  | 
            |
| 72 | |||
| 73 | 1 |         Assert::assertSame('192.168.1.3', $middleware->getIpAddress()); | 
            |
| 74 | 1 | }  | 
            |
| 75 | |||
| 76 | 1 | public function testXForwardedForIpV6()  | 
            |
| 77 |     { | 
            ||
| 78 | 1 | $middleware = new IpAddress(['192.168.1.1']);  | 
            |
| 79 | |||
| 80 | 1 | $request = ServerRequestFactory::fromGlobals([  | 
            |
| 81 | 1 | 'REMOTE_ADDR' => '192.168.1.1',  | 
            |
| 82 | 'HTTP_X_FORWARDED_FOR' => '001:DB8::21f:5bff:febf:ce22:8a2e'  | 
            ||
| 83 | ]);  | 
            ||
| 84 | 1 | $this->runRequest($middleware, $request);  | 
            |
| 85 | |||
| 86 | 1 |         Assert::assertSame('001:DB8::21f:5bff:febf:ce22:8a2e', $middleware->getIpAddress()); | 
            |
| 87 | 1 | }  | 
            |
| 88 | |||
| 89 | 1 | public function testXForwardedForWithInvalidIp()  | 
            |
| 90 |     { | 
            ||
| 91 | 1 | $middleware = new IpAddress(['192.168.1.1']);  | 
            |
| 92 | |||
| 93 | 1 | $request = ServerRequestFactory::fromGlobals([  | 
            |
| 94 | 1 | 'REMOTE_ADDR' => '192.168.1.1',  | 
            |
| 95 | 'HTTP_X_FORWARDED_FOR' => 'foo-bar'  | 
            ||
| 96 | ]);  | 
            ||
| 97 | 1 | $this->runRequest($middleware, $request);  | 
            |
| 98 | |||
| 99 | 1 |         Assert::assertSame('192.168.1.1', $middleware->getIpAddress()); | 
            |
| 100 | 1 | }  | 
            |
| 101 | |||
| 102 | 1 | public function testXForwardedForIpWithTrustedProxy()  | 
            |
| 103 |     { | 
            ||
| 104 | 1 | $middleware = new IpAddress(['192.168.0.1', '192.168.0.2']);  | 
            |
| 105 | |||
| 106 | 1 | $request = ServerRequestFactory::fromGlobals([  | 
            |
| 107 | 1 | 'REMOTE_ADDR' => '192.168.0.2',  | 
            |
| 108 | 'HTTP_X_FORWARDED_FOR' => '192.168.1.3, 192.168.1.2, 192.168.1.1'  | 
            ||
| 109 | ]);  | 
            ||
| 110 | 1 | $this->runRequest($middleware, $request);  | 
            |
| 111 | |||
| 112 | 1 |         Assert::assertSame('192.168.1.3', $middleware->getIpAddress()); | 
            |
| 113 | 1 | }  | 
            |
| 114 | |||
| 115 | 1 | public function testXForwardedForIpWithUntrustedProxy()  | 
            |
| 116 |     { | 
            ||
| 117 | 1 | $middleware = new IpAddress(['192.168.0.1']);  | 
            |
| 118 | |||
| 119 | 1 | $request = ServerRequestFactory::fromGlobals([  | 
            |
| 120 | 1 | 'REMOTE_ADDR' => '192.168.0.2',  | 
            |
| 121 | 'HTTP_X_FORWARDED_FOR' => '192.168.1.3, 192.168.1.2, 192.168.1.1'  | 
            ||
| 122 | ]);  | 
            ||
| 123 | 1 | $this->runRequest($middleware, $request);  | 
            |
| 124 | |||
| 125 | 1 |         Assert::assertSame('192.168.0.2', $middleware->getIpAddress()); | 
            |
| 126 | 1 | }  | 
            |
| 127 | |||
| 128 | 1 | public function testForwardedWithMultipleFor()  | 
            |
| 129 |     { | 
            ||
| 130 | 1 | $middleware = new IpAddress(['192.168.1.1']);  | 
            |
| 131 | |||
| 132 | 1 | $request = ServerRequestFactory::fromGlobals([  | 
            |
| 133 | 1 | 'REMOTE_ADDR' => '192.168.1.1',  | 
            |
| 134 | 'HTTP_FORWARDED' => 'for=192.0.2.43, for=198.51.100.17;by=203.0.113.60;proto=http;host=example.com',  | 
            ||
| 135 | ]);  | 
            ||
| 136 | 1 | $this->runRequest($middleware, $request);  | 
            |
| 137 | |||
| 138 | 1 |         Assert::assertSame('192.0.2.43', $middleware->getIpAddress()); | 
            |
| 139 | 1 | }  | 
            |
| 140 | |||
| 141 | 1 | public function testForwardedWithAllOptions()  | 
            |
| 142 |     { | 
            ||
| 143 | 1 | $middleware = new IpAddress(['192.168.1.1']);  | 
            |
| 144 | |||
| 145 | 1 | $request = ServerRequestFactory::fromGlobals([  | 
            |
| 146 | 1 | 'REMOTE_ADDR' => '192.168.1.1',  | 
            |
| 147 | 'HTTP_FORWARDED' => 'for=192.0.2.60; proto=http;by=203.0.113.43; host=_hiddenProxy, for=192.0.2.61',  | 
            ||
| 148 | ]);  | 
            ||
| 149 | 1 | $this->runRequest($middleware, $request);  | 
            |
| 150 | |||
| 151 | 1 |         Assert::assertSame('192.0.2.60', $middleware->getIpAddress()); | 
            |
| 152 | 1 | }  | 
            |
| 153 | |||
| 154 | 1 | public function testForwardedWithWithIpV6()  | 
            |
| 155 |     { | 
            ||
| 156 | 1 | $middleware = new IpAddress(['192.168.1.1']);  | 
            |
| 157 | |||
| 158 | 1 | $request = ServerRequestFactory::fromGlobals([  | 
            |
| 159 | 1 | 'REMOTE_ADDR' => '192.168.1.1',  | 
            |
| 160 | 'HTTP_FORWARDED' => 'For="[2001:db8:cafe::17]:4711", for=_internalProxy',  | 
            ||
| 161 | ]);  | 
            ||
| 162 | 1 | $this->runRequest($middleware, $request);  | 
            |
| 163 | |||
| 164 | 1 |         Assert::assertSame('2001:db8:cafe::17', $middleware->getIpAddress()); | 
            |
| 165 | 1 | }  | 
            |
| 166 | |||
| 167 | 1 | public function testCustomHeader()  | 
            |
| 168 |     { | 
            ||
| 169 | $headersToInspect = [  | 
            ||
| 170 | 1 | 'Foo-Bar'  | 
            |
| 171 | ];  | 
            ||
| 172 | 1 | $middleware = new IpAddress(['192.168.1.1'], $headersToInspect);  | 
            |
| 173 | |||
| 174 | 1 | $request = ServerRequestFactory::fromGlobals([  | 
            |
| 175 | 1 | 'REMOTE_ADDR' => '192.168.1.1',  | 
            |
| 176 | ]);  | 
            ||
| 177 | 1 |         $request = $request->withAddedHeader('Foo-Bar', '192.168.1.3'); | 
            |
| 178 | 1 | $this->runRequest($middleware, $request);  | 
            |
| 179 | |||
| 180 | 1 |         Assert::assertSame('192.168.1.3', $middleware->getIpAddress()); | 
            |
| 181 | 1 | }  | 
            |
| 182 | |||
| 183 | /**  | 
            ||
| 184 | * @param $middleware  | 
            ||
| 185 | * @param $request  | 
            ||
| 186 | */  | 
            ||
| 187 | 13 | protected function runRequest(IpAddress $middleware, ServerRequestInterface $request): void  | 
            |
| 188 |     { | 
            ||
| 189 | 13 | $response = $this->getResponseMock();  | 
            |
| 190 | 13 |         $handler = CallableHandler::wrap(function (ServerRequestInterface $request) use ($response, $middleware) { | 
            |
| 191 | 13 | $actualMiddleware = IpAddress::fromRequest($request);  | 
            |
| 192 | 13 | Assert::assertSame($middleware, $actualMiddleware);  | 
            |
| 193 | |||
| 194 | 13 | return $response;  | 
            |
| 195 | 13 | });  | 
            |
| 196 | 13 | $acturlResponse = $middleware->process($request, $handler);  | 
            |
| 197 | 13 | Assert::assertSame($response, $acturlResponse);  | 
            |
| 198 | 13 | }  | 
            |
| 199 | }  | 
            ||
| 200 |