| Total Complexity | 78 |
| Total Lines | 363 |
| Duplicated Lines | 25.07 % |
| Changes | 2 | ||
| Bugs | 0 | Features | 0 |
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:
Complex classes like TestOptimizationsMocked 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.
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.
| 1 | # -*- coding: utf-8 -*- |
||
| 41 | class TestOptimizationsMocked(MockerResourceWithNetworkClient): |
||
| 42 | |||
| 43 | resource_module = M |
||
| 44 | |||
| 45 | def test_create(self): |
||
| 46 | |||
| 47 | sample_response_data = load_json( |
||
| 48 | # '..', '..', '..', |
||
| 49 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
| 50 | 'create_response.json' |
||
| 51 | ) |
||
| 52 | |||
| 53 | self.set_response(data=sample_response_data) |
||
| 54 | |||
| 55 | o = Optimization() |
||
| 56 | o.algorithm_type = AlgorithmTypeEnum.TSP |
||
| 57 | o.state = OptimizationStateEnum.MATRIX_PROCESSING |
||
| 58 | o.optimization_factor = OptimizationFactorEnum.DISTANCE |
||
| 59 | o.route_datetime = datetime.datetime(2016, 6, 17) |
||
| 60 | |||
| 61 | r = Optimizations(api_key='test') |
||
| 62 | res = r.create(o) |
||
| 63 | |||
| 64 | # log.debug(self.mock_fluent_request_class.mock_calls) |
||
| 65 | # call(), |
||
| 66 | # call().method('POST'), |
||
| 67 | # call().url('https://www.route4me.com//api.v4/optimization_problem.php'), |
||
| 68 | # call().qs(None), |
||
| 69 | # call().json({'links': {}, 'parameters': {'algorithm_type': 1}}), |
||
| 70 | # call().user_agent('requests/2.18.3 (Linux 4.8.0-53-generic) Route4Me-Python-SDK/0.1.0 CPython/3.5.2'), |
||
| 71 | # call().header('Route4Me-User-Agent', 'requests/2.18.3 (Linux 4.8.0-53-generic) ..'), |
||
| 72 | # call().accept('application/json'), |
||
| 73 | # call().header('Route4Me-Api-Key', 'test'), |
||
| 74 | # call().qs({'format': 'json', 'api_key': 'test'}), |
||
| 75 | # call().send(), |
||
| 76 | # call().send().json() |
||
| 77 | |||
| 78 | # ---------- |
||
| 79 | # assertions |
||
| 80 | mock_freq = self.last_request() |
||
| 81 | mock_freq.method.assert_called_with('POST') |
||
| 82 | mock_freq.url.assert_called_with( |
||
| 83 | 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
| 84 | ) |
||
| 85 | mock_freq.json.assert_called_with(dict(o)) |
||
| 86 | |||
| 87 | # assertions on response |
||
| 88 | assert isinstance(res, Optimization) |
||
| 89 | assert res.ID == '1EDB78F63556D99336E06A13A34CF139' |
||
| 90 | assert res.name == 'Fri, 17 Jun 2016 08:21:59 +0000 UTC' |
||
| 91 | assert res.algorithm_type == AlgorithmTypeEnum.TSP |
||
| 92 | assert res.state == OptimizationStateEnum.MATRIX_PROCESSING |
||
| 93 | assert res.optimization_factor == OptimizationFactorEnum.DISTANCE |
||
| 94 | assert res.member_id == 1 |
||
| 95 | assert res.vehicle_id is None |
||
| 96 | assert res.device_id is None |
||
| 97 | |||
| 98 | assert res.route_datetime == datetime.datetime(2016, 6, 17, tzinfo=pytz.utc) |
||
| 99 | |||
| 100 | def test_create_with_callback(self): |
||
| 101 | |||
| 102 | sample_response_data = load_json( |
||
| 103 | # '..', '..', '..', |
||
| 104 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
| 105 | 'create_response.json' |
||
| 106 | ) |
||
| 107 | |||
| 108 | self.set_response(data=sample_response_data) |
||
| 109 | |||
| 110 | o = Optimization() |
||
| 111 | o.algorithm_type = AlgorithmTypeEnum.TSP |
||
| 112 | o.state = OptimizationStateEnum.MATRIX_PROCESSING |
||
| 113 | o.optimization_factor = OptimizationFactorEnum.DISTANCE |
||
| 114 | |||
| 115 | r = Optimizations(api_key='test') |
||
| 116 | res = r.create( |
||
| 117 | optimization_data=o, |
||
| 118 | optimized_callback_url='https://callback.route4me.com/callback?q=1' |
||
| 119 | ) |
||
| 120 | |||
| 121 | # ---------- |
||
| 122 | # assertions |
||
| 123 | |||
| 124 | log.debug(self.mock_fluent_request_class.mock_calls) |
||
| 125 | # call(), |
||
| 126 | # call().method('POST'), |
||
| 127 | # call().url('https://www.route4me.com/api.v4/optimization_problem.php'), |
||
| 128 | # call().qs({'optimized_callback_url': 'https://callback.route4me.com/callback?q=1'}), |
||
| 129 | # call().json({'links': {}, 'parameters': {'store_route': True, 'algorithm_type': 1, |
||
| 130 | # 'route_max_duration': 86400, 'optimize': 'Distance'}, 'state': 2, 'addresses': []}), |
||
| 131 | # call().user_agent('requests/2.18.3 (Linux 4.8.0-53-generic) Route4Me-Python-SDK/0.1.0 CPython/3.5.2'), |
||
| 132 | # call().header('Route4Me-Agent', |
||
| 133 | # 'requests/2.18.3 (Linux 4.8.0-53-generic) Route4Me-Python-SDK/0.1.0 CPython/3.5.2'), |
||
| 134 | # call().header('Route4Me-Agent-Release', '0.1.0-dev.5'), |
||
| 135 | # call().header('Route4Me-Agent-Commit', None), |
||
| 136 | # call().header('Route4Me-Agent-Build', None), |
||
| 137 | # call().accept('application/json'), |
||
| 138 | # call().header('Route4Me-Api-Key', 'test'), |
||
| 139 | # call().qs({'api_key': 'test', 'format': 'json'}), |
||
| 140 | # call().send(), |
||
| 141 | # call().send().json() |
||
| 142 | |||
| 143 | mock_freq = self.last_request() |
||
| 144 | mock_freq.method.assert_called_with('POST') |
||
| 145 | mock_freq.url.assert_called_with( |
||
| 146 | 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
| 147 | ) |
||
| 148 | mock_freq.json.assert_called_with(dict(o)) |
||
| 149 | mock_freq.qs.assert_any_call({ |
||
| 150 | 'optimized_callback_url': 'https://callback.route4me.com/callback?q=1', |
||
| 151 | }) |
||
| 152 | |||
| 153 | # assertions on response |
||
| 154 | assert isinstance(res, Optimization) |
||
| 155 | assert res.ID == '1EDB78F63556D99336E06A13A34CF139' |
||
| 156 | |||
| 157 | View Code Duplication | def test_get(self): |
|
|
|
|||
| 158 | |||
| 159 | sample_response_data = load_json( |
||
| 160 | # '..', '..', '..', |
||
| 161 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
| 162 | 'get_response.json' |
||
| 163 | ) |
||
| 164 | |||
| 165 | self.set_response(data=sample_response_data) |
||
| 166 | |||
| 167 | r = Optimizations(api_key='test') |
||
| 168 | res = r.get('07372F2CF3814EC6DFFAFE92E22771AA') |
||
| 169 | |||
| 170 | log.debug(self.mock_fluent_request_class.mock_calls) |
||
| 171 | |||
| 172 | # ---------- |
||
| 173 | # assertions |
||
| 174 | mock_freq = self.last_request() |
||
| 175 | mock_freq.method.assert_called_with('GET') |
||
| 176 | mock_freq.url.assert_called_with( |
||
| 177 | 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
| 178 | ) |
||
| 179 | mock_freq.qs.assert_any_call({ |
||
| 180 | 'optimization_problem_id': '07372F2CF3814EC6DFFAFE92E22771AA' |
||
| 181 | }) |
||
| 182 | assert not mock_freq.json.called |
||
| 183 | assert not mock_freq.data.called |
||
| 184 | |||
| 185 | # assertions on response |
||
| 186 | assert isinstance(res, Optimization) |
||
| 187 | assert res.ID == '07372F2CF3814EC6DFFAFE92E22771AA' |
||
| 188 | assert res.name == 'Sunday 10th of April 2016 01:20 AM (+03:00)' |
||
| 189 | assert res.algorithm_type == AlgorithmTypeEnum.CVRP_TW_SD |
||
| 190 | assert res.state == OptimizationStateEnum.OPTIMIZED |
||
| 191 | assert res.optimization_factor == OptimizationFactorEnum.TIME |
||
| 192 | assert res.member_id == 44143 |
||
| 193 | assert res.vehicle_id is None |
||
| 194 | assert res.device_id is None |
||
| 195 | assert res.round_trip is True |
||
| 196 | |||
| 197 | log.debug(res) |
||
| 198 | assert isinstance(res.addresses, list) |
||
| 199 | assert len(res.addresses) > 0 |
||
| 200 | a0 = res.addresses[0] |
||
| 201 | assert isinstance(a0, Address) |
||
| 202 | assert a0.ID == 154456307 |
||
| 203 | |||
| 204 | View Code Duplication | def test_list_no_states(self): |
|
| 205 | |||
| 206 | sample_response_data = load_json( |
||
| 207 | # '..', '..', '..', |
||
| 208 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
| 209 | 'list_response.json' |
||
| 210 | ) |
||
| 211 | |||
| 212 | self.set_response(data=sample_response_data) |
||
| 213 | |||
| 214 | r = Optimizations(api_key='test') |
||
| 215 | res = r.list() |
||
| 216 | |||
| 217 | log.debug(self.mock_fluent_request_class.mock_calls) |
||
| 218 | |||
| 219 | # ---------- |
||
| 220 | # assertions |
||
| 221 | mock_freq = self.last_request() |
||
| 222 | mock_freq.method.assert_called_with('GET') |
||
| 223 | mock_freq.url.assert_called_with( |
||
| 224 | 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
| 225 | ) |
||
| 226 | mock_freq.qs.assert_any_call({}) |
||
| 227 | |||
| 228 | assert not mock_freq.json.called |
||
| 229 | assert not mock_freq.data.called |
||
| 230 | |||
| 231 | # assertions on response |
||
| 232 | assert isinstance(res, list) |
||
| 233 | assert isinstance(res, PagedList) |
||
| 234 | assert res.total == 447 |
||
| 235 | assert res.limit is None |
||
| 236 | assert res.offset is None |
||
| 237 | |||
| 238 | res0 = res[0] |
||
| 239 | assert isinstance(res0, Optimization) |
||
| 240 | assert res0.ID == '7EC3FC88737C29E93A54E88243ACBC77' |
||
| 241 | assert res0.name == 'Fri, 20 May 2016 12:43:46 +0000 UTC' |
||
| 242 | assert res0.algorithm_type == AlgorithmTypeEnum.CVRP_TW_SD |
||
| 243 | assert res0.state == OptimizationStateEnum.INITIAL |
||
| 244 | assert res0.optimization_factor == OptimizationFactorEnum.DISTANCE |
||
| 245 | assert res0.member_id == 1 |
||
| 246 | assert res0.vehicle_id is None |
||
| 247 | assert res0.device_id is None |
||
| 248 | assert res0.round_trip is True |
||
| 249 | |||
| 250 | def test_list_with_states(self): |
||
| 251 | |||
| 252 | sample_response_data = load_json( |
||
| 253 | # '..', '..', '..', |
||
| 254 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
| 255 | 'list_response.json' |
||
| 256 | ) |
||
| 257 | |||
| 258 | self.set_response(data=sample_response_data) |
||
| 259 | |||
| 260 | r = Optimizations(api_key='test') |
||
| 261 | res = r.list(states=[OptimizationStateEnum.INITIAL, OptimizationStateEnum.OPTIMIZED]) |
||
| 262 | |||
| 263 | log.debug(self.mock_fluent_request_class.mock_calls) |
||
| 264 | |||
| 265 | # ---------- |
||
| 266 | # assertions |
||
| 267 | mock_freq = self.last_request() |
||
| 268 | mock_freq.method.assert_called_with('GET') |
||
| 269 | mock_freq.url.assert_called_with( |
||
| 270 | 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
| 271 | ) |
||
| 272 | mock_freq.qs.assert_any_call({ |
||
| 273 | 'state': '1,4' |
||
| 274 | }) |
||
| 275 | |||
| 276 | assert not mock_freq.json.called |
||
| 277 | assert not mock_freq.data.called |
||
| 278 | |||
| 279 | # assertions on response |
||
| 280 | assert isinstance(res, list) |
||
| 281 | assert isinstance(res, PagedList) |
||
| 282 | assert res.total == 447 |
||
| 283 | assert res.limit is None |
||
| 284 | assert res.offset is None |
||
| 285 | |||
| 286 | res0 = res[0] |
||
| 287 | assert isinstance(res0, Optimization) |
||
| 288 | |||
| 289 | def test_update(self): |
||
| 290 | |||
| 291 | sample_response_data = load_json( |
||
| 292 | # '..', '..', '..', |
||
| 293 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
| 294 | 'reoptimization_response.json' |
||
| 295 | ) |
||
| 296 | |||
| 297 | sample_optimization_data = load_json( |
||
| 298 | # '..', '..', '..', |
||
| 299 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
| 300 | 'reoptimization_request.json' |
||
| 301 | ) |
||
| 302 | |||
| 303 | self.set_response(data=sample_response_data) |
||
| 304 | |||
| 305 | ep = Optimizations(api_key='test') |
||
| 306 | res = ep.update( |
||
| 307 | ID='07372F2CF3814EC6DFFAFE92E22771AA', |
||
| 308 | optimization_data=sample_optimization_data, |
||
| 309 | ) |
||
| 310 | |||
| 311 | log.debug(self.mock_fluent_request_class.mock_calls) |
||
| 312 | |||
| 313 | # ---------- |
||
| 314 | # assertions |
||
| 315 | mock_freq = self.last_request() |
||
| 316 | mock_freq.method.assert_called_with('PUT') |
||
| 317 | mock_freq.url.assert_called_with( |
||
| 318 | 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
| 319 | ) |
||
| 320 | mock_freq.qs.assert_any_call({ |
||
| 321 | 'optimization_problem_id': '07372F2CF3814EC6DFFAFE92E22771AA', |
||
| 322 | 'reoptimize': '0', |
||
| 323 | }) |
||
| 324 | mock_freq.json.assert_called_with(sample_optimization_data) |
||
| 325 | assert not mock_freq.data.called |
||
| 326 | |||
| 327 | # assertions on response |
||
| 328 | assert isinstance(res, Optimization) |
||
| 329 | assert res.ID == '07372F2CF3814EC6DFFAFE92E22771AA' |
||
| 330 | assert res.name == 'Sunday 10th of April 2016 01:20 AM (+03:00)' |
||
| 331 | assert res.algorithm_type == AlgorithmTypeEnum.CVRP_TW_SD |
||
| 332 | assert res.state == OptimizationStateEnum.INITIAL |
||
| 333 | assert res.optimization_factor == OptimizationFactorEnum.TIME |
||
| 334 | assert res.member_id == 44143 |
||
| 335 | assert res.vehicle_id is None |
||
| 336 | assert res.device_id is None |
||
| 337 | assert res.round_trip is True |
||
| 338 | |||
| 339 | def test_remove(self): |
||
| 340 | |||
| 341 | sample_response_data = load_json( |
||
| 342 | |||
| 343 | # '..', '..', '..', |
||
| 344 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
| 345 | 'remove_response.json' |
||
| 346 | ) |
||
| 347 | |||
| 348 | self.set_response(data=sample_response_data) |
||
| 349 | |||
| 350 | opt_id = 'DE62B03510AB5A6A876093F30F6C7BF5' |
||
| 351 | r = Optimizations(api_key='test') |
||
| 352 | res = r.remove(ID=opt_id) |
||
| 353 | |||
| 354 | # log.debug(self.mock_fluent_request_class.mock_calls) |
||
| 355 | |||
| 356 | # ---------- |
||
| 357 | # assertions |
||
| 358 | mock_freq = self.last_request() |
||
| 359 | mock_freq.method.assert_called_with('DELETE') |
||
| 360 | mock_freq.url.assert_called_with( |
||
| 361 | 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
| 362 | ) |
||
| 363 | mock_freq.qs.assert_any_call({ |
||
| 364 | 'optimization_problem_id': opt_id |
||
| 365 | }) |
||
| 366 | mock_freq.json.assert_called_once_with(None) |
||
| 367 | |||
| 368 | assert not mock_freq.data.called |
||
| 369 | |||
| 370 | assert res is True |
||
| 371 | # assertions on response |
||
| 372 | |||
| 373 | def test_remove_failed(self): |
||
| 374 | |||
| 375 | self.set_response(data=None) |
||
| 376 | |||
| 377 | opt_id = 'DE62B03510AB5A6A876093F30F6C7BF5' |
||
| 378 | r = Optimizations(api_key='test') |
||
| 379 | |||
| 380 | with pytest.raises(Route4MeApiError) as exc_info: |
||
| 381 | r.remove(ID=opt_id) |
||
| 382 | |||
| 383 | log.debug(self.mock_fluent_request_class.mock_calls) |
||
| 384 | |||
| 385 | exc = exc_info.value |
||
| 386 | assert exc is not None |
||
| 387 | |||
| 388 | # TODO: implement this! |
||
| 389 | # assert exc.method == 'DELETE' |
||
| 390 | # assert exc.url == 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
| 391 | |||
| 392 | def test_reoptimize(self): |
||
| 393 | |||
| 394 | self.set_response(data={}) |
||
| 395 | |||
| 396 | ep = Optimizations(api_key='test') |
||
| 397 | |||
| 398 | with mock.patch.object(ep, 'update') as mock_update: |
||
| 399 | ep.reoptimize(ID='07372F2CF3814EC6DFFAFE92E22771AA') |
||
| 400 | |||
| 401 | mock_update.assert_called_once_with( |
||
| 402 | ID='07372F2CF3814EC6DFFAFE92E22771AA', |
||
| 403 | reoptimize=True |
||
| 404 | ) |
||
| 405 |